创建 n children 个,每个都有自己的管道

Creating n children each with their own pipe

我无法理解 pipefork,至少在实践中难以理解。我想创建 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吧