所以我有一些代码,我正在努力将N个孩子用N个不同的文件做一些事情并收集一些信息。父母只是在读书,而孩子们只是在写作。如果一个孩子在另一个孩子之前完成,我想开始在父母中处理这些数据,而其他孩子仍在运行。
我在这里制作N管道
int pipefds[nFiles*2];
int k;
for(k = 0; k < nFiles; k++)
{
if(pipe(pipefds[k*2]))
{
/* pipe failed */
}
}
然后我分叉N个进程,并希望它们对文件执行某些操作并将其发送给父进程
int i;
for(i = 0; i < nFiles; i++)
{
pid = fork();
if(pid < 0)
{
/* error */
}
else if(pid == 0)
{
/*child */
close(pipefds[i*2]); //I think I want to close the Read End of each child's pipe
getData(file[i]); // do something with the file this process is handling
write(fd[i*2 +1], someData, sizeof(someData); // write something to the write end of the child's pipe
exit(0);
}
else
{
/*parent*/
if(i = nFiles -1) //do I have to make this condition so that I start once all processes have been started??
{
int j;
for(j = 0; j < nFiles; j++)
{
close(pipefds[j*2+1]); //close all the parents write ends
}
/*Here I want to pick the pipe that finished writing first and do something with it */
}
}
我是否必须等待for循环的最后一次迭代才能开始执行父内容(因为我希望在执行任何操作之前启动所有进程)?另外如何在pipefds中找到已经完成写入的管道,这样我可以在其他人运行时开始处理它?谢谢!
答案 0 :(得分:0)
可能最简单的解决方案是先创造所有孩子。然后围绕poll
或select
运行单独的循环。当您在其中一个管道端获得读取命中时,将数据读入缓冲区。如果该读取指示管道的另一端已关闭,则可以开始处理该子项的数据。 (不要忘记从poll
或select
的集合中移除该管道。)当所有儿童的管道关闭时,您就完成了。