问题描述
我正在尝试了解 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 在退出时会这样做,父在 close(fd[1])
时会这样做。
所以你陷入了僵局。在第二个 wait()
返回之前您不会关闭 FD,但在您关闭 FD 之前它不会返回。