C 对管道实现感到困惑

C 对管道实现感到困惑,c,unix,pipe,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

管道的一个实现是:

#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 */

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

管道调用将返回用于单向通信的读描述符和写描述符。但是,写入程序不需要读取描述符fd[0]。并且,读取器不需要写入描述符fd[1]。因此,fork调用后的每个进程都会关闭它不需要的描述符,并使用它确实需要的描述符

因此,在您的示例中,家长是编写者。它首先关闭fd[0],然后关闭STD_输出。然后它复制fd[1],由于fd[1]可用,因此它现在将在STD_输出中。由于管道的输出描述符现在已复制,因此也不再需要它,因此它已关闭。现在,当编写器将某些内容写入STD_输出时,它将写入管道的输出描述符

作为读取器的子级执行类似的逻辑,但在另一个描述符上执行。它首先关闭fd[1],然后关闭STD_输入。然后它复制fd[0],这导致描述符位于STD_输入中。复制后,管道的输入描述符不再需要,所以它被关闭。现在,当读卡器从STD_输入中读取某些内容时,它将从管道的输入描述符中读取。

管道调用将返回单向通信的读描述符和写描述符。但是,写入程序不需要读取描述符fd[0]。并且,读取器不需要写入描述符fd[1]。因此,fork调用后的每个进程都会关闭它不需要的描述符,并使用它确实需要的描述符

因此,在您的示例中,家长是编写者。它首先关闭fd[0],然后关闭STD_输出。然后它复制fd[1],由于fd[1]可用,因此它现在将在STD_输出中。由于管道的输出描述符现在已复制,因此也不再需要它,因此它已关闭。现在,当编写器将某些内容写入STD_输出时,它将写入管道的输出描述符


作为读取器的子级执行类似的逻辑,但在另一个描述符上执行。它首先关闭fd[1],然后关闭STD_输入。然后它复制fd[0],这导致描述符位于STD_输入中。复制后,管道的输入描述符不再需要,所以它被关闭。现在,当读卡器从STD_输入中读取某些内容时,它将从管道的输入描述符中读取。

对不起,问题不明确,我已经更新了它。我了解dup前关闭的第一次使用,但不了解dup后关闭的第二次调用。@richard:您不需要两份文件描述符,是吗?一旦你复制了它,你就不需要原件了。我现在明白了,我误解了这个例子。谢谢,我很抱歉,问题不明确,我已经更新了。我了解dup前关闭的第一次使用,但不了解dup后关闭的第二次调用。@richard:您不需要两份文件描述符,是吗?一旦你复制了它,你就不需要原件了。我现在明白了,我误解了这个例子。谢谢
close(fd[0]);   /* this file descriptor not needed anymore */