为什么 wait() 函数(系统调用)从不 return (无限等待)
Why wait() funtion ( system call ) never return ( make an infinity wait)
我想模拟管道命令:ls |排序 | wc -l 通过编写一些代码但我遇到了一个奇怪的问题(我可以通过删除该行来解决它但我不知道它是错误的原因)
当我删除最后一个等待命令时,它 运行 完全正确并完成。但是当我添加这个时,它会无限等待。
int main()
{
int pfds[2];
int pfds1[2];
pipe(pfds); // create a pipe
pid_t pid = fork(); // create child proess
if (pid == 0) // child process
{
dup2(pfds[1],1); // change the stdout to pipe
close(pfds[0]);
execlp("ls", "ls", NULL); // run the ls command
}
else { // main process
wait(0); // wait for the child process
pipe(pfds1); // make a pipe
pid_t npid = fork(); // create child process
if (npid == 0) // child process
{
dup2(pfds[0],0); // change the stdin to pipe
close(pfds[1]);
dup2(pfds1[1], 1); // get data from pipe
close(pfds1[0]);
execlp("sort", "sort", NULL); // run sort command ( combine with above is ls | sort )
}
else { // main process
wait(0); // this line will make infinity wait
dup2(pfds[0], 0);
close(pfds[1]);
execlp("wc", "wc", "-l", NULL); // run wc -l command
}
}
return 0;
}
你没有关闭你应该关闭的 fds。请记住,只有在所有文件描述符都关闭后,文件句柄才会关闭。例如,如果您不小心,可能 ls
已经完成但 sort
没有意识到这一点,因为缺少 close
.
此外,您的代码容易出现死锁。如果 ls
要输出大量数据,它将写入第一个管道,直到它满了并阻塞。 parent 没有清空管道,而是等待 child 结束。死锁。
确保关闭不再需要的 fds,并在等待任何结束之前每隔 children 启动一次。
int pfds1[2]; pipe(pfds1);
pid_t pid1 = fork();
if (!pid1) {
close(pfds1[0]);
dup2(pfds1[1], 1); close(pfds1[1]);
execlp("ls", "ls", NULL);
}
close(pfds1[1]);
int pfds2[2]; pipe(pfds2);
pid_t pid2 = fork();
if (!pid2) {
close(pfds2[0]);
dup2(pfds1[0], 0); close(pfds1[0]);
dup2(pfds2[1], 1); close(pfds2[1]);
execlp("sort", "sort", NULL);
}
close(pfds2[1]);
pid_t pid3 = fork();
if (!pid3) {
dup2(pfds2[0], 0); close(pfds2[0]);
execlp("wc", "wc", "-l", NULL);
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
我想模拟管道命令:ls |排序 | wc -l 通过编写一些代码但我遇到了一个奇怪的问题(我可以通过删除该行来解决它但我不知道它是错误的原因) 当我删除最后一个等待命令时,它 运行 完全正确并完成。但是当我添加这个时,它会无限等待。
int main()
{
int pfds[2];
int pfds1[2];
pipe(pfds); // create a pipe
pid_t pid = fork(); // create child proess
if (pid == 0) // child process
{
dup2(pfds[1],1); // change the stdout to pipe
close(pfds[0]);
execlp("ls", "ls", NULL); // run the ls command
}
else { // main process
wait(0); // wait for the child process
pipe(pfds1); // make a pipe
pid_t npid = fork(); // create child process
if (npid == 0) // child process
{
dup2(pfds[0],0); // change the stdin to pipe
close(pfds[1]);
dup2(pfds1[1], 1); // get data from pipe
close(pfds1[0]);
execlp("sort", "sort", NULL); // run sort command ( combine with above is ls | sort )
}
else { // main process
wait(0); // this line will make infinity wait
dup2(pfds[0], 0);
close(pfds[1]);
execlp("wc", "wc", "-l", NULL); // run wc -l command
}
}
return 0;
}
你没有关闭你应该关闭的 fds。请记住,只有在所有文件描述符都关闭后,文件句柄才会关闭。例如,如果您不小心,可能 ls
已经完成但 sort
没有意识到这一点,因为缺少 close
.
此外,您的代码容易出现死锁。如果 ls
要输出大量数据,它将写入第一个管道,直到它满了并阻塞。 parent 没有清空管道,而是等待 child 结束。死锁。
确保关闭不再需要的 fds,并在等待任何结束之前每隔 children 启动一次。
int pfds1[2]; pipe(pfds1);
pid_t pid1 = fork();
if (!pid1) {
close(pfds1[0]);
dup2(pfds1[1], 1); close(pfds1[1]);
execlp("ls", "ls", NULL);
}
close(pfds1[1]);
int pfds2[2]; pipe(pfds2);
pid_t pid2 = fork();
if (!pid2) {
close(pfds2[0]);
dup2(pfds1[0], 0); close(pfds1[0]);
dup2(pfds2[1], 1); close(pfds2[1]);
execlp("sort", "sort", NULL);
}
close(pfds2[1]);
pid_t pid3 = fork();
if (!pid3) {
dup2(pfds2[0], 0); close(pfds2[0]);
execlp("wc", "wc", "-l", NULL);
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);