【六】 进程间通信——(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); }
【六】 进程间通信——(PIPE)无名管道
最新推荐文章于 2025-09-07 17:43:44 发布