复用管道处理多消息:父进程与子进程通信异常排查
问题分析与修复方案
先梳理你代码里的核心问题和修复点:
核心阻塞原因:错误使用wait(NULL)
你的子进程是无限循环(while(true)),永远不会调用exit退出,而父进程每次发送消息后调用wait(NULL),会一直阻塞等待某个子进程终止——但子进程根本不会结束,这直接导致父进程卡住,无法回到输入流程。
其他关键问题
- 子进程未清理无关管道描述符:fork后子进程继承了所有4个管道的读写句柄,除了自己管道的读端,其他所有管道的读写句柄都要关闭,否则管道无法正确触发EOF,还会造成资源泄漏。
- 未处理
read返回值:当管道写端被关闭时,read会返回0表示无数据可读,此时子进程应该退出循环,而不是继续死等。 - 变量未定义/未初始化:
query未声明、rand()未初始化(需要srand(time(NULL))生成随机数)、fd[t][W]中的t是未定义变量。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <time.h> #include <sys/wait.h> #define R 0 #define W 1 int main(int argc, char const *argv[]) { char query[100]; // 声明query变量 int fd[4][2]; // 初始化随机数种子 srand(time(NULL)); // 创建4个管道,增加错误处理 for(int i = 0; i < 4; i++){ if(pipe(fd[i]) == -1){ perror("pipe failed"); exit(EXIT_FAILURE); } } pid_t fils_pid[4]; // 创建4个子进程 for(int i = 0; i < 4; i++){ if((fils_pid[i] = fork()) == 0){ // 子进程:关闭自己管道的写端,关闭其他所有管道的读写端 close(fd[i][W]); for(int j = 0; j < 4; j++){ if(j != i){ close(fd[j][R]); close(fd[j][W]); } } char buf[100]; ssize_t bytes_read; // 处理read返回值,直到管道关闭(返回0) while((bytes_read = read(fd[i][R], buf, sizeof(buf)-1)) > 0){ buf[bytes_read] = '\0'; // 确保字符串结束 printf("子进程%d处理:Query: %s", i+1, buf); } close(fd[i][R]); exit(EXIT_SUCCESS); } else if(fils_pid[i] == -1){ perror("fork failed"); exit(EXIT_FAILURE); } } // 父进程:关闭所有管道的读端 for(int i = 0; i < 4; i++){ close(fd[i][R]); } // 父进程循环获取输入并发送 while(true){ int idx = rand() % 4; printf("Enter a query: "); // 处理fgets的错误或EOF(比如Ctrl+D终止输入) if(fgets(query, sizeof(query), stdin) == NULL){ break; } // 发送数据,包含字符串结束符 write(fd[idx][W], query, strlen(query) + 1); // 移除原来的wait(NULL),因为子进程不会主动退出 } // 父进程退出前关闭所有管道写端,让子进程收到EOF后退出 for(int i = 0; i < 4; i++){ close(fd[i][W]); } // 等待所有子进程退出 for(int i = 0; i < 4; i++){ waitpid(fils_pid[i], NULL, 0); } printf("Bye bye!\n"); return 0; }
修复说明
- 去掉了父进程中的
wait(NULL),改为在程序退出前用waitpid等待所有子进程结束,避免不必要的阻塞。 - 子进程清理了所有无关的管道描述符,避免资源泄漏和管道状态异常。
- 处理了
read的返回值,当管道写端关闭时,子进程会退出循环并终止。 - 补全了未定义的变量,初始化了随机数种子,增加了管道创建、fork失败的错误处理。
内容的提问来源于stack exchange,提问作者Tomás Guija Valiente
相关产品推荐
相关产品推荐

