从管道读取后read函数阻塞进程问题求助
管道read阻塞进程的问题分析与解决
问题原因
你的代码里,主进程创建管道后没有关闭管道的两个文件描述符fd[0]和fd[1]。根据管道的工作规则:只有当所有指向管道写端的文件描述符都被关闭时,读端的read调用才会返回0(表示EOF),否则read会一直阻塞等待数据。
在你的执行流程里:
- 主进程创建管道后fork出子进程1,主进程自身仍持有管道的读写两端
- 子进程12关闭了写端
fd[1]并退出,但主进程的fd[1]还处于打开状态 - 子进程1的
read循环会一直阻塞,因为它认为还有进程可能往管道里写入数据
解决方案
在主进程的default分支里,fork完成后立即关闭管道的两个文件描述符——主进程不需要使用这个管道,保留打开的描述符会干扰管道的EOF判断。
修改后的代码:
#include<stdio.h> #include<stdlib.h> #include<sys/wait.h> #include<string.h> #include <unistd.h> int nbrecar=5; int main() { int fd[2]; pipe(fd); char *buffer=(char *)malloc(sizeof(char)*256); int pid=fork(); switch(pid) { case 0://fils 1 //pere 2 int pid2=fork(); if (pid2==0)//fils 12 // pere 3 { close(fd[0]); while(nbrecar>1) { if(sprintf(buffer,"le nbre des cars restant:%i\n",nbrecar-1)==-1){printf("Erreur");}; nbrecar--; write(fd[1],buffer,strlen(buffer)); } close(fd[1]); exit(0); } else//fils 1 { close(fd[1]); char c; while(read(fd[0],&c,1)==1) {printf("%c",c);}; close(fd[0]); exit(8); } break; default: // 主进程关闭管道的读写端 close(fd[0]); close(fd[1]); wait(NULL); free(buffer); } return 0; }
验证说明
修改后,主进程关闭了管道的两端,当子进程12关闭写端并退出后,管道的所有写端都已关闭,子进程1的read会返回0,循环正常退出,进程不再阻塞,能够正常结束。
内容的提问来源于stack exchange,提问作者SBAT
相关产品推荐
相关产品推荐

