为什么我不能在等待后关闭管道?

Why can't I close pipes after wait?

我正在尝试了解 wait() 的工作原理。这是在命令行

中模仿ls -F -1 | nl的c程序
    pipe(fd); // create the pipe

    pid1 = fork(); //fork child 1

    if (pid1 == 0) // child 1
    {
        close(fd[0]);                       // close read end of the pipe
        dup2(fd[1], 1);                     // child 1 redirects stdout to write to the pipe
        execlp("ls", "bin/ls", "-F", NULL); // execute ls -F
        close(fd[1]);                       // close write end of the pipe
    }

    pid2 = fork(); //fork child 2

    if (pid2 == 0) // child 2
    {
        close(fd[1]);                  // close write end of the pipe
        dup2(fd[0], 0);                // child 2 redirects stdin to read from the pipe
        execlp("nl", "usr/bin", NULL); // execute nl
        close(fd[0]);                  // close read end of the pipe
    }

    if (pid1 != 0 && pid2 != 0) // parent process
    {
        wait(NULL);   // wait for a child
        wait(NULL);   // wait for another child
        close(fd[0]); // close read end of parent pipe
        close(fd[1]); // close write end of parent pipe
    }

我最初认为 wait(NULL)close(fd) 的顺序无关紧要。但显然确实如此。为什么此代码在将 close(fd[1]) 下方的两个 wait(NULL) 移动正常时保持 运行 不打印任何内容?

nlstdin 上获得 EOF 之前不会退出。这不会发生,直到 parent 和 child 1 关闭管道的写入端。 Child 1 退出时会执行此操作,parent 会在退出时执行此操作 close(fd[1]).

所以你陷入了僵局。在第二个 wait() return 秒之前您不会关闭 FD,但是在您关闭 FD 之前它不会 return。