【六】 进程间通信——(PIPE)无名管道


【六】  进程间通信——(PIPE)无名管道


#include <unistd.h>

 int pipe2(int pipefd[2], int flags);

The array pipefd is used to return two file descriptors,pipefd[0]  refers  to  the  read end of the pipe.  pipefd[1] refers to the write end of the pipe.

一、无名管道(PIPE)的特点:

(1)只能用于具有亲缘关系的进程之间。
(2)半双工(即同一时间只能对管道有一种操作),具有读端和写端
(3)管道时一种特殊的文件,可以使用文件IO如Read()、Write()函数来操作,但不能够用lseek()来定位操作。
(4)管道是在内存里,不用我们主动删除
(5)管道是基于对列实现的,而且有大小限制
我们先运行一个例子,这里只是给大家一个印象——PIPE是一种特殊的文件,当一个管道建立时,会对应的打开两个
文件描述符(下图的“3”,“4”):其他的就不要深究了,我们要详略得当的进行我们的无名管道的学习。
 
无名管道通信的构成: 通过关闭相应的描述符。

二、父进程读管道关闭,子进程写管道关闭。

三、程序设计思路:

因为无名管道是用于"具有亲缘关系的进程之间"通信的,所以我们先设计一个进程,然后再fork一个子进程,父进程关闭读端,子进程关闭写端,然后然让父进程向管道写数据,子进程独处管道里的内容然后打印到终端上。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#define MAX 64
int main()
{
	char buf[MAX];
	int fd[2],status,ret;
	if(pipe(fd)<0)
	{
		perror("Fail to pipe");
		exit(-1);
	}
	pid_t pid;
	if((pid = fork())<0)
	{
		exit(0);
	}
	else if(pid >0 )
	{
		close(fd[1]);
		while((ret = read(fd[0],buf,sizeof(buf)))>0)
		{
			if(ret < 0)
			{
				wait(&status);
				printf("The son is exit with status [%d] \n",status);
			}
			printf("recv:%s",buf);
		}
	}
	else //son pid
	{
		close(fd[0]);
		while(fgets(buf,sizeof(buf),stdin)!=NULL)
		{
			if(strncmp(buf,"quit",4)==0)
			{
				printf("son will exit with status '5' .\n");
				exit(5);
			}
			write(fd[1],buf,sizeof(buf));
		}
	}
	return 0;
}
测试系统最多能开多少个pipe,以此来说明,系统的文件描述符是有限的,我们应该习惯打开使用过后,关闭文件描述符。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>

int main()
{
	int fd[2];
	pid_t pid;
	ssize_t n = 0;
	
	if (pipe(fd) == -1)
	{
		perror("pipe");
		exit(-1);
	}

	if ((pid = fork()) == -1)
	{
		perror("fork");
		exit(-1);
	}

	if (pid == 0)//child write
	{
		close (fd[0]);

		while (1)
		{
			n += write(fd[1], "a", 1);//abc\n
			//ssize_t write(int fd, const void *buf, size_t count);
			printf("n=%d\n", n);
		}
	}
	else //parent read
	{
		close (fd[1]);
		int status;
		wait(&status);
		printf("%#x\n", status);
	}

	exit(0);
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值