C 为什么可以';我等一下再关上水管好吗?

C 为什么可以';我等一下再关上水管好吗?,c,process,C,Process,我试图了解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);

我试图了解
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)
的顺序无关紧要。但显然是这样。为什么在将两个
wait(NULL)
移动到
close(fd[1])
下方时,此代码保持运行而不打印任何内容?

nl
stdin
上获得EOF之前不会退出。在父级和子级1都关闭管道的写入端之前,不会发生这种情况。子1将在退出时执行此操作,父1在关闭时执行此操作(fd[1])


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

nl
将不会退出,直到它在
stdin上获得EOF。在父级和子级1都关闭管道的写入端之前,不会发生这种情况。子1将在退出时执行此操作,父1在关闭时执行此操作(fd[1])


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

这不是您昨天发布的代码吗?您甚至没有改变我当时指出的明显问题,比如尝试在
execlp()
之后运行代码。您不需要最后一个
if()
。孩子们都使用
execlp()。我删除了参数,是的,这次我试图理解wait()是如何工作的。如果父命令打开管道,子命令将不会得到EOF,因此
wait()
调用将不会返回,因此关闭操作将不会执行。家长不打算使用管道;它必须先关闭所有管道描述符,然后才能等待其子项。这不是昨天发布的代码吗?您甚至没有改变我当时指出的明显问题,比如尝试在
execlp()
之后运行代码。您不需要最后一个
if()
。孩子们都使用
execlp()。我删除了参数,是的,这次我试图理解wait()是如何工作的。如果父命令打开管道,子命令将不会得到EOF,因此
wait()
调用将不会返回,因此关闭操作将不会执行。家长不打算使用管道;它必须先关闭所有管道描述符,然后才能等待其子项。哦,我现在明白了。非常感谢。哦,我现在明白了。非常感谢。