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

来源:互联网 发布:飞鱼网络电视手机版 编辑:程序博客网 时间:2024/05/17 05:59

【六】  进程间通信——(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 64int 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);}