创建 n children 个,每个都有自己的管道
Creating n children each with their own pipe
我无法理解 pipe
和 fork
,至少在实践中难以理解。我想创建 n
children 每个人都有自己的管道。
我想做这样的事情:
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
}
}
}
但这样做会导致 children 自己制作流程,这不是我想要的。
此外,您将如何使 parent 和 child 运行 同时发生,其中 child 不断写入管道,而 parent,可以访问每个 child 的管道,从中读取,用它做一些事情,然后丢弃它以便 child 可以向管道写入新的东西?
您将需要一个文件描述符数组,其大小足以容纳每个 child 的一对文件描述符。
parent 代码将创建管道。每个 child 进程都应该关闭任何兄弟进程的管道。确切的机制取决于您如何创建管道;有多种可行的选择。
if (r == 0)
代码将执行 child 进程并应确保它退出而不是继续循环。
parent 进程将继续创建其他 child 进程,然后再进入其自己的处理循环。
您将需要决定如何确定哪些 child 人已写入数据,以便 parent 可以无阻塞地读取数据。您可以使用 select()
或 poll()
或它们的变体,或者 parent 可能使管道的读取端 non-blocking,或...
在评论中你问“……人们提到了线程,但这可以用管道实现吗?”,答案是 "yes, it's possible — though it isn't clear that it is necessary or desirable"。
Would you happen to have sample code doing what you've described?
写起来可能比找起来简单。 be_childish()
函数负责做任何 child 应该做的事情。它不应该 return。如果是这样,那将被报告为失败。
您没有详细说明 child 流程的作用,因此很难填补其中的空白。
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;
}
注意:此代码尚未接近编译器,更不用说 运行。应该是有bug吧
我无法理解 pipe
和 fork
,至少在实践中难以理解。我想创建 n
children 每个人都有自己的管道。
我想做这样的事情:
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
}
}
}
但这样做会导致 children 自己制作流程,这不是我想要的。
此外,您将如何使 parent 和 child 运行 同时发生,其中 child 不断写入管道,而 parent,可以访问每个 child 的管道,从中读取,用它做一些事情,然后丢弃它以便 child 可以向管道写入新的东西?
您将需要一个文件描述符数组,其大小足以容纳每个 child 的一对文件描述符。
parent 代码将创建管道。每个 child 进程都应该关闭任何兄弟进程的管道。确切的机制取决于您如何创建管道;有多种可行的选择。
if (r == 0)
代码将执行 child 进程并应确保它退出而不是继续循环。
parent 进程将继续创建其他 child 进程,然后再进入其自己的处理循环。
您将需要决定如何确定哪些 child 人已写入数据,以便 parent 可以无阻塞地读取数据。您可以使用 select()
或 poll()
或它们的变体,或者 parent 可能使管道的读取端 non-blocking,或...
在评论中你问“……人们提到了线程,但这可以用管道实现吗?”,答案是 "yes, it's possible — though it isn't clear that it is necessary or desirable"。
Would you happen to have sample code doing what you've described?
写起来可能比找起来简单。 be_childish()
函数负责做任何 child 应该做的事情。它不应该 return。如果是这样,那将被报告为失败。
您没有详细说明 child 流程的作用,因此很难填补其中的空白。
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;
}
注意:此代码尚未接近编译器,更不用说 运行。应该是有bug吧