38.Linux 无名管道

通信对象不一样,通信方式不一样

1、管道:一种是无名管道、一种是有名管道

在文件系统中无文件结点

无名管道

通信原理:

38.Linux 无名管道_第1张图片

 管道文件是一个特殊的文件,是由队列来实现的。

在文件IO中创建一个文件或打开一个文件是由open函数来实现的,它不能创建管道文件。只能用pipe函数来创建管道。

文件open——只能创建或打开普通文件,它不能创建管道文件。只能用pipe函数来创建管道。

创建管道——pipe

函数形式:int pipe(int fd[2]);

 #include

 int pipe(int pipefd[2]);

功能:创建管道,为系统调用:unistd.h

参数:就是得到的文件描述符。可见有两个文件描述符:fd[0]和fd[1],管道有一个读端fd[0]用来读和一个写端fd[1]用来写,这个规矩不能变。

返回值:成功是0,出错是-1 

例一:pipe函数使用。

#include 
#include 
#include 
int main()
{
        int fd[2];
        int ret;
        ret=pipe(fd);
        if(ret<0)
        {
                printf("creat pipe failure\n");
                return -1;
        }
        printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
        return 0;
}

执行结果如下:

 创建管道成功,fd[0]=3,fd[1]=4.

管道有一个读端fd[0]用来读和一个写端fd[1]用来写

#include 
#include 
#include 
int main()
{
	int fd[2];
	int ret;
	char write_buf[]="hello kiki";
	char read_buf[128]={0};
	ret=pipe(fd);
	if(ret<0)
	{
		printf("creat pipe failure\n");
		return -1;
	}
	printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);

	write(fd[1],write_buf,sizeof(write_buf));
	//start read from pipe
	
	read(fd[0],read_buf,128);
	printf("read_buf=%s\n",read_buf);

	close(fd[0]);
	close(fd[1]);
	return 0;
}

执行结果如下:

注意:

-管道是创建在内存中的,进程结束,空间释放,管道就不存在了;

-管道中的东西,读完了就删除了;队列——出队以后队列的内容就已经不在了

-如果管道中没有东西可读,则会阻塞。

例2:验证读阻塞

 
#include 
#include 
#include 
#include 
int main()
{
	int fd[2];
	int ret;
	char write_buf[]="hello kiki";
	char read_buf[128]={0};
	ret=pipe(fd);
	if(ret<0)
	{
		printf("creat pipe failure\n");
		return -1;
	}
	printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);

	write(fd[1],write_buf,sizeof(write_buf));
	//start read from pipe
	
	read(fd[0],read_buf,128);
	printf("read_buf=%s\n",read_buf);

	//second read from pipe
	
	memset(read_buf,0,128);

	read(fd[0],read_buf,128);
	printf("second read after\n ");

	close(fd[0]);
	close(fd[1]);
	return 0;
}

执行结果如下:

 

例3:验证写阻塞:可以计算出内核开辟的管道有多大。65536 

#include 
#include 
#include 
#include 
int main()
{
	int fd[2];
	int ret;
	int i=0;
	char write_buf[]="hello kiki";
	char read_buf[128]={0};
	ret=pipe(fd);
	if(ret<0)
	{
		printf("creat pipe failure\n");
		return -1;
	}
	printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
	while(i<6500)
	{
		write(fd[1],write_buf,sizeof(write_buf));
		i++;
	}

	printf("write pipe end\n");

	close(fd[0]);
	close(fd[1]);
	return 0;
}

执行结果如下:

 如果写阻塞,后面的printf语句不会执行,则说明管道写满了

例4:实现进程通信

#include 
#include 
#include 
#include 
int main()
{
	pid_t pid;
	int fd[2];
	char process_inter=0;
	int ret=pipe(fd);
	if(ret<0)
	{
		printf("creat pipe failure\n");
		return -1;
	}
	printf("creat pipe sucess\n");
	pid = fork();
	
	if(pid==0)
	{
		int i=0;
		read(fd[0],&process_inter,1);//if pipe empty sleep
		while(process_inter==0);
		for(i=0;i<5;i++)
		{
			printf("this is child process i=%d\n",i);
			usleep(100);
		}
	}
	if(pid>0)
	{
		int i=0;
		for(i=0;i<5;i++)
		{
			printf("this is parent process i=%d\n",i);
			usleep(100);
		}
		process_inter=1;
		sleep(3);
		write(fd[1],&process_inter,1);
	}
	while(1);
	return 0;
}

执行结果如下:

38.Linux 无名管道_第2张图片

 

无名管道的缺点:不能实现不是父子进程(亲缘关系)之间的通信。

你可能感兴趣的:(linux)