【linux进程间通信】无名管道

📅 发布时间:2026/7/15 15:36:08 👁️ 浏览次数:
【linux进程间通信】无名管道
多用于具有亲缘关系的进程间进行单向通信特点半双工通信数据单向流动以字节流的方式通信数据格式由用户自行定义多用于父子进程间通信也可用于其他亲缘关系进程间通信实现原理父进程调用pipe函数会创建两个文件读管道文件写管道文件这两个文件对应的文件节点为pipe inode, pipe inode为无名管道的具体实现​ 父进程调用fork函数创建子进程子进程拷贝父进程文件表由于父子进程文件表内容相同指向的file相同所以最终父子进程操作的pipe管道相同。父子进程都能看到管道内存空间所以父子进程能正常通信由于对于无名管道来说每次只能半双工工作要么父进程写子进程读要么父进程读子进程写。要想实现全双工的话需要父进程调用两次pipe创建两个管道如下图注意无亲缘关系进程文件表不能访问相同文件进程间无法访问相同的pipe管道所以不能通过无名管道进程通信。实现过程无名管道操作//建立无名管道 int pipe(int pipefd[2]); int pipe2(int pipefd[2], int flags); //读写无名管道 参考io关闭 ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); //关闭无名管道 int close(int fd);功能pipe或pipe2函数用于创建一个无名管道pipe用于进程间通信。参数pipefd整型数组用于存储管道的文件描述符。pipefd[0]读文件描述符。pipefd[1]写文件描述符。flags用于设置管道的标志位参数可以是0或者以下下常量的安慰或O_NONBLOCK设置非阻塞模式即读取何写入管道时不会阻塞进程。 O_CLOEXEC设置在execve系统调用执行的时候关闭管道返回值成功返回0失败返回-1并设置errno使用示例int fd[2] {0}; void test() { pid_t pid fork(); //创建子进程 if(pid 0) { close(fd[1]); //子进程关闭读写端 while(1) { char rbuf[100] {0}; read(fd[0], rbuf, 100); //子进程读数据 } close(fd[0]); } else if(pid 0) close(fd[0]); //父进程关闭读端 } int main(int argc, char* argv[]) { pipe(fd); //创建pipe test(); while(1) { write(fd[1], TEST_STRING, sizeof(TEST_STRING)); //父进程写数据 sleep(1); } close(fd[1]); return 0; }使用无名管道实现父子进程通信#include unistd.h #include stdio.h #include string.h int pipe_test() { int fd[2]; int ret pipe(fd); if(ret -1) { perror(pipe); return -1; } ret fork(); if(ret 0) { //子进程 close(fd[0]); //子进程写数据关闭 读 端 #define TEST_STRING 123456789 while(1) { write(fd[1], TEST_STRING, strlen(TEST_STRING)); sleep(1); } }else if(ret 0) { //父进程 close(fd[1]); //父进程读数据关闭 写 端 while(1) { char* buf[1024]; read(fd[0], buf, 1024); printf(buf:%s\n, buf); } }else { } return 0; } int main(int argc, char* argv[]) { pipe_test(); return 0; }