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

如何通过单个管道接收两个子进程返回值并在父进程中求和

问题根因
  • 管道本质是字节流传输,只要写入的数据长度小于PIPE_BUF(Linux下默认4096字节),单个write操作是原子的,不会和其他进程的write穿插。你遇到的不是值覆盖,是父进程只调用了1次read(),只读取了1个int的长度,管道中还残留了另一个子进程写入的int数据未被读取。
  • 原有代码还存在两处不规范的资源操作:子进程2未关闭管道读端fd[0],父进程未关闭不需要的管道写端fd[1],可能引发不必要的资源泄漏或异常。
单管道修复方案

不用更换为多管道,只需要修改父进程的读取逻辑,读取两次int值再求和即可,修改后的代码如下:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
    int s1 = 0, s2=0, sum=0;
    int n= atoi(argv[1]);
    pid_t  child1, child2,wpid;
    int status = 0 ;
    int count = 0;
    int count2 = 0;
    int fd[2];
    if (pipe(fd)< 0){
        printf("An error ocurred with opening the pipe\n");
        return 1;
    }

    child1 = fork();

    if(child1<0){
        printf("Fork Failed for child 1.\n");
        return 1;
    }else if(child1 == 0){
        // 子进程1:关闭不需要的读端
        close(fd[0]);
        while(count<=n){
            if(count%2 == 0){
                s1 = s1 + count;
            }
            count = count + 1;
        }
        write(fd[1], &s1, sizeof(int));
        close(fd[1]);
        exit(0);
    }else{
        child2 = fork();
        if(child2<0){
            printf("failed to fork child 2.");
            return 1;
        }
        if(child2 == 0){
            // 子进程2:关闭不需要的读端
            close(fd[0]);
            while(count2<=10){
                if(count2%2 != 0){
                    s2 = s2 + count2;
                }
                count2 = count2 +1;
            }
            write(fd[1], &s2, sizeof(int));
            close(fd[1]);
            exit(0);
        }else{
            // 父进程:关闭不需要的写端
            close(fd[1]);
            // 等待所有子进程退出
            while((wpid = wait(&status))>0);
            // 读两次,分别取两个子进程的结果
            read(fd[0], &s1, sizeof(int));
            read(fd[0], &s2, sizeof(int));
            sum = s1 + s2;
            printf("子进程1结果:%d,子进程2结果:%d,二者之和:%d\n", s1, s2, sum);
            close(fd[0]);
        }
    }
    return 0;
}
补充说明

如果需要明确区分两个返回值对应哪个子进程,可以选择两种方案:

  • 每个子进程写入的时候带上自己的进程标识,父进程读取后按标识区分
  • 创建两个独立的管道,分别对应和两个子进程的通信,避免顺序混淆

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:27:03