C语言pipe与fork实现管道程序无输出问题排查
问题分析与修复代码
你的代码运行无输出的核心问题是父进程错误地关闭了用于读取子进程结果的管道读端,后续尝试读取时自然无法获取数据。以下是具体问题点和修复后的完整代码:
核心错误点
- 父进程中,注释写的是"关闭p21的写端",但实际执行的是
close(p21[0])——而p21[0]是管道的读端,父进程需要通过这个读端读取子进程返回的拼接字符串,提前关闭后read操作会失败,导致没有输出。 - 子进程初始化
concat_str为"."属于多余操作,读取父进程发送的字符串时会覆盖该初始值,无实际意义。 - 缺少必要的系统头文件,会导致编译失败(你提到移除了主库,这是编译层面的必要依赖)。
修复后的完整代码
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> #include <stdlib.h> // 两个管道:p12用于父进程向子进程发数据,p21用于子进程向父进程返回结果 // 管道数组中,0是读端,1是写端 int p12[2]; int p21[2]; char fixed_str[] = "at tutorialspoint"; char input_str[100]; int main() { pid_t P; // 创建管道 if (pipe(p12) == -1 || pipe(p21) == -1) { fprintf(stderr, "Pipe creation failed\n"); return 1; } // 读取用户输入 scanf("%99s", input_str); // 创建子进程 P = fork(); if (P < 0) { fprintf(stderr, "Fork failed\n"); return 1; } // 父进程逻辑 else if (P > 0) { char concat_str[100]; // 关闭p12的读端(父进程只写p12) close(p12[0]); // 向子进程发送输入字符串 write(p12[1], input_str, strlen(input_str) + 1); close(p12[1]); // 等待子进程完成处理 wait(NULL); // 关闭p21的写端(父进程只读p21) close(p21[1]); // 读取子进程返回的拼接字符串 read(p21[0], concat_str, 100); printf("Concatenated string: %s\n", concat_str); close(p21[0]); exit(0); } // 子进程逻辑 else { char concat_str[100]; // 关闭p12的写端(子进程只读p12) close(p12[1]); // 读取父进程发送的字符串 read(p12[0], concat_str, 100); close(p12[0]); // 拼接固定字符串 int k = strlen(concat_str); for (int i = 0; i < strlen(fixed_str); i++) { concat_str[k++] = fixed_str[i]; concat_str[k] = '\0'; } // 关闭p21的读端(子进程只写p21) close(p21[0]); // 向父进程返回拼接结果 write(p21[1], concat_str, strlen(concat_str) + 1); close(p21[1]); exit(0); } return 0; }
关键修复说明
- 修正父进程管道操作:将父进程中错误的
close(p21[0])改为close(p21[1])(关闭p21的写端,父进程不需要写这个管道),保留读端用于读取结果。 - 移除多余初始化:子进程中
concat_str不需要初始化为".",直接定义空数组即可,避免不必要的干扰。 - 补充必要头文件:添加了编译和运行所需的标准库及系统调用头文件,确保代码能正常编译。
- 优化输出格式:在
printf末尾添加换行符,让输出更规范。
内容的提问来源于stack exchange,提问作者Jason Beswilan
相关产品推荐
相关产品推荐

