父子进程管道通信问题:子进程无法正确读取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
相关产品推荐
相关产品推荐

