为什么我不能在等待后关闭管道?
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)
移动正常时保持 运行 不打印任何内容?
nl
在 stdin
上获得 EOF 之前不会退出。这不会发生,直到 parent 和 child 1 关闭管道的写入端。 Child 1 退出时会执行此操作,parent 会在退出时执行此操作 close(fd[1])
.
所以你陷入了僵局。在第二个 wait()
return 秒之前您不会关闭 FD,但是在您关闭 FD 之前它不会 return。
我正在尝试了解 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)
移动正常时保持 运行 不打印任何内容?
nl
在 stdin
上获得 EOF 之前不会退出。这不会发生,直到 parent 和 child 1 关闭管道的写入端。 Child 1 退出时会执行此操作,parent 会在退出时执行此操作 close(fd[1])
.
所以你陷入了僵局。在第二个 wait()
return 秒之前您不会关闭 FD,但是在您关闭 FD 之前它不会 return。