【发布时间】:2021-07-03 13:44:35
【问题描述】:
我目前正在测试一个使用管道执行 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],&status,0);
waitpid(id[1],&status,0); // This works
return 0;
}
谢谢。
【问题讨论】:
-
您的评论不正确。如果取消注释该行,
wc命令会执行,但它永远不会完成,因此永远不会打印任何数据(它的输出缓冲区永远不会被刷新)。如果您留下注释行,wc命令只会终止,因为父级退出并且其所有文件描述符都已关闭。