我无法理解pipe
和fork
,至少在实践中实现它。我想用自己的烟斗创造n
儿童。
我想过做的事情:
int main(void) {
int fd[2];
for (int i = 0; i < n; i++) {
pipe(fd);
r = fork();
if (r == 0) {
// do child stuff
} else if (r > 0) {
// do parent stuff
}
}
}
但这样做会导致孩子们制作自己的过程,这不是我想要的。
此外,你将如何使父和子同时运行,其中孩子经常写入管道和父母,通过访问每个孩子的管道,从中读取,用它做某事,然后丢弃它这样孩子可以在管道上写点新东西?
您将需要一个足够大的文件描述符数组,以便为每个子项提供一对文件描述符。
父代码将创建管道。每个子进程都应该关闭任何兄弟进程的管道。其确切的机制取决于您如何创建管道;有多种可行的选择。
if (r == 0)
代码将执行子进程,并应确保它退出而不是继续循环。
父进程将继续创建其他子进程,然后再进入自己的处理循环。
您将需要决定如何确定哪些子项具有写入数据,以便父级可以不受阻塞地读取它。您可以使用select()
或poll()
或其中的变体,或者父级可能会使管道的读取端无阻塞,或者......
在一个评论中,你会问“......人们已经提到了线程,但这可能是用管道吗?”,答案是“是的,它是可能的 - 虽然不清楚它是否必要或可取”。
您是否碰巧有示例代码执行您所描述的内容?
写作可能比找到更简单。 be_childish()
函数负责做孩子应该做的事情。它不应该回来。如果是,则报告为失败。你没有多说儿童过程的作用,所以很难填补那里的空白。
int main(void)
{
enum { NUM_CHILDREN = 5 };
int fd[NUM_CHILDREN][2];
for (int i = 0; i < NUM_CHILDREN; i++)
{
pipe(fd[i]);
int pid = fork();
if (pid < 0)
…error exit…
if (pid == 0)
{
// Child
// Close sibling pipes
for (int j = 0; j < i; j++)
{
close(fd[j][0]);
close(fd[j][1]);
}
close(fd[i][0]); // Close read end of pipe
be_childish(fd[i][1]);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < NUM_CHILDREN; i++)
close(fd[i][1]); // Close write end of every child's pipe
// setup complete, unless you need to make the read end of the pipes non-blocking
// do parental stuff, reading from the various child pipes
for (int i = 0; i < NUM_CHILDREN; i++)
close(fd[i][0]); // Close read end of every child's pipe
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
printf("Child %d exited with status 0x%.4X\n", corpse, status);
return 0;
}
注意:此代码并非靠近编译器,更不用说运行了。可能存在漏洞。