pid_t kids[argc];
int childCount = argc - 1;
int fd[2];
/* create the pipe*/
if (pipe(fd) == -1) {
fprintf(stderr ,"Pipe failed");
return 1;
for(i=0; i < childCount; i++) {
kids[i] = fork();
if(kids[i] < 0){
//fork fail
}
else if(kids[i] == 0) {
/* child process */
sum = max + min;//sum and dif are results from each child process
dif = max - min;
/* close the unused end of pipe, in this case, the read end */
close(fd[READ_END]);
/* write to the pipe */
write(fd[WRITE_END], &sum, sizeof(sum));
write(fd[WRITE_END], &dif, sizeof(dif));
/* close write end */
close(fd[WRITE_END]);
exit(0);
}
else {
waitpid(kids[i], &status, 0);
close(fd[WRITE_END]);
read(fd[READ_END], &sum, sizeof(float));
read(fd[READ_END], &dif, sizeof(float));
close(fd[READ_END]);
}
}
以上是代码,稍微简化了一下
我想做的是等待任何孩子完成并处理其数据,然后重复这一点,直到所有孩子都完成
有人能告诉我如何将子项生成的数据传递给父级吗?
答案 0 :(得分:0)
你没有提到你当前代码的问题是什么,你展示的代码没有编译,所以我只能猜测这是你真实代码的近似值。
尽管如此,这引起了我的注意:
你永远不会在循环之前关闭if (pipe(fd) == -1)
的主体,这意味着循环是if
主体的一部分。这可能不是你想要的,虽然我不确定它是否是拼写错误/复制粘贴错误。也许在实际代码中你关闭了if
。
父进程的代码是错误的:因为它在for
循环内运行,所以你在管道的写入和读取结束时反复调用close(2)
。这将导致close(2)
在循环的第二次迭代时返回错误(EBADF
),这是您公然忽略的。另外,在第二次迭代,分叉的孩子会尝试关闭没有按&#39的管道的读通道;吨存在了(因为我们只是分叉父进程关闭前一个迭代中两端再次分叉之前),和然后它试图写入一个不存在的管道。
要解决此问题,您必须确保父母不会关闭管道直到每个孩子都完成它。在循环内的父级中不要close(2)
;相反,在循环之后执行:
for(i=0; i < childCount; i++) {
kids[i] = fork();
if(kids[i] < 0){
//fork fail
}
else if(kids[i] == 0) {
/* child process */
sum = max + min;//sum and dif are results from each child process
dif = max - min;
/* close the unused end of pipe, in this case, the read end */
close(fd[READ_END]);
/* write to the pipe */
write(fd[WRITE_END], &sum, sizeof(sum));
write(fd[WRITE_END], &dif, sizeof(dif));
/* close write end */
close(fd[WRITE_END]);
exit(0);
}
else {
waitpid(kids[i], &status, 0);
read(fd[READ_END], &sum, sizeof(float));
read(fd[READ_END], &dif, sizeof(float));
}
}
close(fd[READ_END]);
close(fd[WRITE_END]);
由于您等待每个孩子在循环中终止,因此可以保证在仍有活动的作者时不会关闭管道。