如何在C/C++中通过管道将父进程数据传递给子进程标准输入?
进程间管道通信问题修复方案
问题根源分析
你的代码存在几个关键错误,导致子进程无法正确接收父进程的数据:
- 子进程错误等待父进程退出,引发死锁
- 父进程向管道写入数据的方式错误,未传递实际字符串内容
- 管道文件描述符未正确关闭,导致子进程无法检测到管道结束
- 写入数据时未添加分隔符,子进程的输入读取逻辑无法正确解析
修正后的父进程代码
#include <iostream> #include <unistd.h> #include <string> auto main() -> int { int fd[2]; // fd[0] - 读端; fd[1] - 写端 // 创建管道并检查是否成功 if (pipe(fd) == -1) { std::cerr << "Pipe creation failed\n"; return 1; } // 创建子进程 int id = fork(); if (id == -1) // fork失败 { std::cerr << "Could not fork a process\n"; return 2; } else if (id == 0) // 子进程逻辑 { // 将管道读端重定向到标准输入 dup2(fd[0], STDIN_FILENO); // 关闭不需要的管道描述符 close(fd[0]); close(fd[1]); // 启动子进程程序 execlp("./calculator", "./calculator", NULL); std::cerr << "Failed to run child\n"; return 3; } else // 父进程逻辑 { // 关闭不需要的管道读端 close(fd[0]); std::string number; while (std::cin >> number) { std::cout << "I read from user to parent: " << number << "\n"; // 写入字符串内容,加上换行符作为分隔符 if (write(fd[1], number.c_str(), number.size()) == -1) { std::cerr << "Could not write into pipe\n"; return 4; } // 写入换行符,让子进程的cin能正确识别每个数字 write(fd[1], "\n", 1); } // 关闭管道写端,通知子进程数据传输结束 close(fd[1]); } return 0; }
修正后的子进程(calculator)代码
#include <fstream> #include <iostream> auto main() -> int { std::ofstream output("./output.txt"); if (!output.is_open()) { std::cerr << "Failed to open output file\n"; return 1; } int received; while (std::cin >> received) { output << "I read from parent to child: " << received << "\n"; } // 显式关闭文件(可选,作用域结束会自动关闭) output.close(); return 0; }
关键修改点说明
- 移除子进程中的
waitpid调用:子进程不需要等待父进程退出,否则父进程在等待用户输入时,子进程会一直阻塞,完全无法执行后续逻辑。 - 修正管道写入逻辑:
- 使用
number.c_str()获取字符串的实际内容指针,number.size()获取实际长度,替代原有的&number和sizeof(std::string) - 每个数字后写入换行符,因为子进程用
std::cin >> received读取整数,需要换行符作为分隔符,否则会一直等待输入结束
- 使用
- 正确关闭管道描述符:
- 父进程fork后立即关闭管道读端(fd[0]),因为父进程只需要写管道
- 子进程dup2后关闭fd[0]和fd[1],避免管道的读端被多个进程持有,导致子进程无法检测到管道关闭
- 添加文件打开检查:子进程中检查输出文件是否成功打开,方便排查文件权限问题
内容的提问来源于stack exchange,提问作者Demo_13B
相关产品推荐
相关产品推荐

