对管道实施感到困惑

时间:2012-08-23 23:53:36

标签: c unix pipe

管道的一个实现是:

#define STD_INPUT 0
#define STD_OUTPUT 1
pipeline(char *process1, char *process2)
{
    int fd[2];

    pipe(&fd[0]);
    if (fork() != 0) {
        /* The parent process executes these statements. */
        close(fd[0]);
        close(STD_OUTPUT);
        dup(fd[1]);
        close(fd[1]);    /* this file descriptor not needed anymore */
        execl(process1, process1, 0);
    }
    else {
        /* The child process executes these statements. */
        close(fd[1]);
        close(STD_INPUT);
        dup(fd[0]);
        close(fd[0]);   /* this file descriptor not needed anymore */
        execl(process2, process2, 0);
   }
}

我对使用每个dup调用后面的两个语句感到困惑。

close(fd[1]);    /* this file descriptor not needed anymore */

close(fd[0]);   /* this file descriptor not needed anymore */

我被告知不再需要描述符,但对我来说,这些描述符代表了管道的每一端,为什么它们不再需要呢?

1 个答案:

答案 0 :(得分:4)

pipe调用返回单向通信的读描述符和写描述符。但是,编写器不需要读取描述符(fd[0])。并且,读者不需要写描述符(fd[1])。因此,fork调用之后的每个进程都会关闭它不需要的描述符,并使用它所需的描述符。

所以,父亲是你的例子中的作家。它首先关闭fd[0],然后关闭STD_OUTPUT。然后它会复制fd[1],现在它将在STD_OUTPUT中,因为它可用。由于管道的输出描述符现在是重复的,因此不再需要它,因此它被关闭。现在,当作者向STD_OUTPUT写入内容时,它将写入管道的输出描述符。

作为读者的孩子执行类似的逻辑,但在另一个描述符上。它首先关闭fd[1],然后关闭STD_INPUT。然后它复制fd[0],这导致描述符在STD_INPUT中。在复制之后,不再需要管道的输入描述符,因此它被关闭。现在,当读者从STD_INPUT读取内容时,它将从管道的输入描述符中读取。