You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;
}

关键修改点说明

  1. 移除子进程中的waitpid调用:子进程不需要等待父进程退出,否则父进程在等待用户输入时,子进程会一直阻塞,完全无法执行后续逻辑。
  2. 修正管道写入逻辑:
    • 使用number.c_str()获取字符串的实际内容指针,number.size()获取实际长度,替代原有的&number和sizeof(std::string)
    • 每个数字后写入换行符,因为子进程用std::cin >> received读取整数,需要换行符作为分隔符,否则会一直等待输入结束
  3. 正确关闭管道描述符:
    • 父进程fork后立即关闭管道读端(fd[0]),因为父进程只需要写管道
    • 子进程dup2后关闭fd[0]和fd[1],避免管道的读端被多个进程持有,导致子进程无法检测到管道关闭
  4. 添加文件打开检查:子进程中检查输出文件是否成功打开,方便排查文件权限问题

内容的提问来源于stack exchange,提问作者Demo_13B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:25:59