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

父子进程管道通信问题:子进程无法正确读取chunkcount

管道通信数据顺序错误问题

我正在开发一个项目,需求是:父进程根据输入的count值创建动态数组,再将数组拆分为近似相等的块,发送给N个子进程(N由用户输入指定)。目前遇到管道通信问题:当父进程将数组分块后通过管道发送给子进程时,子进程无法确定每个块的整数数量(因块是近似相等的,用bonus变量处理数量差异)。我创建了chunkcount变量尝试传递给子进程,但出现异常。

从输出可见,父进程的chunkcount值正确,但子进程接收到的chunkcount值错误。排查发现,子进程先读取chunkcount时,实际读到的是先发送的数组元素,chunkcount数据在其后,导致无法先获取chunkcount来读取对应数量的整数。

输出示例

1 2 3 4 5 6 3

1 2 3 4 5 6 

I'm the parent --> 2179292
I'm child # 1 , with pid: 2179338
I'm child # 3 , with pid: 2179340
I'm child # 2 , with pid: 2179339
process 2179292 is sending data
chunkcount: 2

 child chunkcount: 1
chunkcount: 2
chunkcount: 2


 child chunkcount: 3
 child chunkcount: 5
2 child 1 recieved data
6 2 1909636606 32513 1 child 3 recieved data
4 2 1909636606 child 2 recieved data
Child PID 2179338 terminated with return status 0 
Child PID 2179339 terminated with return status 0 
Child PID 2179340 terminated with return status 0 

父进程相关代码

chunk_size = (count / N);
int bonus = count - (chunk_size * N);
int start;
int end;

// 为所有子进程初始化管道的多维数组
int fd[N][2];

int l = 0;
  

// 将数组拆分为块
// 父进程逻辑
for (start = 0, end = chunk_size; start < count; start = end, end = start + chunk_size)
{
    int chunkcount = 0;
    if (bonus)
    {
        end++;
        bonus--;
    }
    // l 是要发送数据的子进程编号

    for (int o = start; o < end; o++)
    {  

       if (write(fd[l][WRITE], &ar[o], sizeof(int)) < 0)
        {
            perror("writing to pipe");
            exit(1);
        }
       chunkcount++;
    }
    printf("chunkcount: %d\n", chunkcount);
     if (write(fd[l][WRITE], &chunkcount, sizeof(int)) < 0)
        {
            perror("writing to pipe");
            exit(1);
        }
    l++;
}

子进程接收数据函数

int child_work(int child_num, int fd[], int arr[])
{

    int ay[10];
    int chunkcount;
    
    if (close(fd[WRITE]) < 0)
    {
        perror("closing fd[WRITE]");
        exit(1);
    }

    if(read(fd[READ], &chunkcount, sizeof(int)) < 0){
        perror("reading chunknum");
        exit(1);
    }

    printf("\n child chunkcount: %d\n", chunkcount);

    if(read(fd[READ], ay, chunkcount * sizeof(int)) < 0){
        perror("reading chunknum");
        exit(1);
    }

  
    for (int t = 0; t< chunkcount; t++){
    printf("%d ", ay[t]);
    }
    // 循环读取文件描述符中的数据
   /*  for (int fk = 0; fk < count; fk++)
    {
        if (read(fd[READ], &arr[fk], sizeof(int)) < 0)
        {
            perror("reading to pipe");
            exit(1);
        }
        printf("%d ", arr[fk]);
    } */
    sleep(1);
    printf("child %d recieved data\n", child_num + 1);

    
}

问题原因与解决方法

问题根源

父进程先发送数组元素,再发送chunkcount,但子进程尝试先读取chunkcount,导致读到的是数组的第一个元素,后续读取数据自然全部错位。

修复方案

调整父进程的发送顺序:先发送chunkcount,再发送对应数量的数组元素。这样子进程就能先获取正确的chunkcount,再读取对应长度的数组数据。

修改后的父进程代码片段:

for (start = 0, end = chunk_size; start < count; start = end, end = start + chunk_size)
{
    int chunkcount = 0;
    if (bonus)
    {
        end++;
        bonus--;
    }
    // 直接通过end-start计算chunkcount,避免循环累加出错
    chunkcount = end - start;
    printf("chunkcount: %d\n", chunkcount);
    
    // 第一步:先发送chunkcount
    if (write(fd[l][WRITE], &chunkcount, sizeof(int)) < 0)
    {
        perror("writing chunkcount to pipe");
        exit(1);
    }
    
    // 第二步:发送数组元素
    for (int o = start; o < end; o++)
    {  
       if (write(fd[l][WRITE], &ar[o], sizeof(int)) < 0)
        {
            perror("writing array element to pipe");
            exit(1);
        }
    }
    l++;
}

额外优化

  • 用end - start直接计算chunkcount,无需在循环中累加,减少出错概率。
  • 父进程发送完数据后,记得关闭对应管道的写端,避免子进程读取时阻塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:35:23