如何解决子进程未在管道中退出
我目前正在测试一个使用管道执行 Linux 命令 echo Hello | wc
的程序。
main()
中的父进程产生两个子进程,第一个执行 echo Hello
,第二个执行 wc
。这两个进程通过管道进行通信。
但是,当我在两个子进程上调用 waitpid()
时,只有第二个进程退出。第一个进程成功运行 execvp()
,但挂在那里。
这是代码的假设输出:
command 0
command 0 should exit
command 1
1 1 6
如果我取消注释行 waitpid(id[0],&status,0);
那么输出是
command 0
command 0 should exit
command 1
int test(pid_t id[])
{
int i;
int pipefd[2];
char *cat_args[] = {"echo","Hello",NULL};
char *grep_args[] = {"wc",NULL};
// make a pipe
pipe(pipefd);
for(i = 0; i < 2; i++){
id[i] = fork();
if (id[i] == -1){
printf("Unable to create child process");
fprintf(stderr,"fork() failed to spawn child process");
exit(1);
}
else if (id[i] == 0){
printf("command ");
printf("%d\n",i);
if (i == 0){
dup2(pipefd[0],STDIN_FILENO);
}
else if (i == 1){
dup2(pipefd[1],STDOUT_FILENO);
}
// Close pipes
close(pipefd[0]);
close(pipefd[1]);
if (i == 1){
execvp(*cat_args,cat_args); //exit(0) normally
}
else if (i == 0){
printf("command 0 should exit\n");
execvp(*grep_args,grep_args);
printf("command 0 exited\n"); //If first child exits,should print it out
}
}
}
return 0;
}
这里是主要功能:
int main(int argc,char **argv)
{
pid_t id[2];
test(id);
int status;
// If this is uncommented,the piped Linux command is never ran
// and main() never exits
//waitpid(id[0],0);
waitpid(id[1],0); // This works
return 0;
}
谢谢。
解决方法
运行 wc
的子进程挂起,因为尽管运行 echo Hello
的子进程死了,管道仍然可读。 wc
仍在等待通过管道读取某些内容。
为什么管道仍然可读?因为您没有在父进程中关闭它,即执行两个 fork
的进程。因此,父进程仍然可以读取和写入管道,而 wc
子进程在 read()
上保持阻塞并且永远不会收到 EOF。
顺便说一句,您的 printf("command 0 exited\n")
没有用,因为在成功 execvp()
后没有执行任何操作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。