使用自己的管道创建n个孩子

问题描述 投票:2回答:1

我无法理解pipefork,至少在实践中实现它。我想用自己的烟斗创造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
        }
    }
}

但这样做会导致孩子们制作自己的过程,这不是我想要的。

此外,你将如何使父和子同时运行,其中孩子经常写入管道和父母,通过访问每个孩子的管道,从中读取,用它做某事,然后丢弃它这样孩子可以在管道上写点新东西?

c pipe fork pipeline interprocess
1个回答
0
投票

您将需要一个足够大的文件描述符数组,以便为​​每个子项提供一对文件描述符。

父代码将创建管道。每个子进程都应该关闭任何兄弟进程的管道。其确切的机制取决于您如何创建管道;有多种可行的选择。

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;
}

注意:此代码并非靠近编译器,更不用说运行了。可能存在漏洞。

© www.soinside.com 2019 - 2024. All rights reserved.