我正在尝试编写一个使用管道和叉子执行ls | wc
的C程序,但是我无法弄清楚我的代码出了什么问题。当我运行下面的代码时,什么也不会返回。
int main() {
pid_t p1, p2;
int fd1[2];
pipe(fd1);
p1 = fork();
if (p1 == 0) {
close(STDOUT_FILENO);
dup2(fd1[1], STDOUT_FILENO);
close(fd1[0]);
execlp("ls", "ls", (char *)NULL);
} else {
p2 = fork();
if (p2 == 0) {
dup2(fd1[0], STDIN_FILENO);
close(fd1[0]);
close(fd1[1]);
execlp("wc", "wc", (char *)NULL);
} else {
waitpid(p2, 0, WUNTRACED);
waitpid(p1, 0, WUNTRACED);
}
}
return 0;
}
答案 0 :(得分:1)
您没有明确解释该程序在做什么,您认为这是错误的。但是,当我自己运行此程序时(在添加了适当的标题后,以后,请不要将它们放在您的问题之外),它会挂起,直到按Control-C为止。我将假设这是您不想要的,而您想要想要的是让它打印wc
的输出然后退出。
程序挂起,因为在调用fd1[1]
时,wait
在父进程中仍处于打开状态。 wc
将不会收到EOF指示,直到所有引用管道写端的文件描述符的 all 全部关闭。但是父进程在两个子进程都退出之前不会关闭管道的写侧,并且wc
在获得EOF之前不会退出,因此您将陷入僵局。
您需要在close(fd1[1])
的紧前面的第一个if
的父侧添加p2 = fork()
。这足以消除僵局。您还应该在close(fd1[0])
调用之前,在 second if
的父级添加waitpid
。而且您还应该检查所有操作是否有错误。