子进程执行顺序似乎是错误的,但有效

Child-Process execution order seems wrong, but works

为什么下面的代码会执行命令:

"cat /etc/passwd | wc -l"

而不是

"wc -l | cat /etc/passwd"?

尽管调试语句的顺序是

b

a

 int main() {
    pid_t pid;
    int fd[2];

    int stdOut = dup(1);

    pid = fork();
    if (pid == 0) {
        pipe(fd);
        pid = fork();
        if (pid == 0) {
            close(fd[0]);
            dup2(fd[1], STDOUT_FILENO);
            close(fd[1]);

            write(stdOut, "a\n", 2);

            execlp("cat", "cat", "/etc/passwd", NULL);
        }
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);
        close(fd[0]);

        write(stdOut, "b\n", 2);

        execlp("wc", "wc", "-l", NULL);
    }
    wait(NULL);
    return 0;
}

pipedup2close的使用决定了两个进程如何连接,而不是执行顺序。第一个运行的进程可能会阻塞 readwrite 对管道的访问,直到另一个进程分别发送或接收数据。

执行顺序不能错,因为没有指定。 parent 或 child 中的任何一个都可能要等待一些东西,调度程序不保证资源的公平分配。也许创建一个child进程需要一些时间,所以parent可能会达到

write(stdOut, "b\n", 2);

在 child 达到

之前
write(stdOut, "a\n", 2);

标记 ab 的显示顺序与管道中发生的情况无关。
在它们产生的那一刻,两个过程之间没有同步。
cat 命令写入其标准输出,该标准输出被重定向到管道的 write 侧。
wc 命令从其标准输入中读取,该标准输入从管道的 read 侧重定向。
因此,在任何情况下,数据都会通过管道从 cat 传输到 wc