C 为什么waitpid挂起而不是获取所有子进程?
我试图模拟shell处理前台命令,但在获取子进程时遇到了麻烦。我在下面的代码中使用fork生成多个进程C 为什么waitpid挂起而不是获取所有子进程?,c,operating-system,system,system-calls,waitpid,C,Operating System,System,System Calls,Waitpid,我试图模拟shell处理前台命令,但在获取子进程时遇到了麻烦。我在下面的代码中使用fork生成多个进程 while (currCmdListNode != list_end(¤tPipeline->commands)) { if (fork() == 0) { printf("Child created with pid %d \n", getpid());
while (currCmdListNode != list_end(¤tPipeline->commands)) {
if (fork() == 0)
{
printf("Child created with pid %d \n", getpid());
currentCmd = list_entry(currCmdListNode, struct esh_command, elem);
execvp(currentCmd->argv[0], currentCmd->argv);
}
currCmdListNode = list_next(currCmdListNode);
}
while((pid = waitpid(-1, &status, WUNTRACED)) > 0)
{
if (WIFEXITED(status))
{
printf("child %d terminated normally with exit status=%d\n", pid, WEXITSTATUS(status));
}
else
{
printf("child %d terminated abnormally\n", pid);
}
}
然后,我尝试使用以下代码从父进程获取所有这些进程
while (currCmdListNode != list_end(¤tPipeline->commands)) {
if (fork() == 0)
{
printf("Child created with pid %d \n", getpid());
currentCmd = list_entry(currCmdListNode, struct esh_command, elem);
execvp(currentCmd->argv[0], currentCmd->argv);
}
currCmdListNode = list_next(currCmdListNode);
}
while((pid = waitpid(-1, &status, WUNTRACED)) > 0)
{
if (WIFEXITED(status))
{
printf("child %d terminated normally with exit status=%d\n", pid, WEXITSTATUS(status));
}
else
{
printf("child %d terminated abnormally\n", pid);
}
}
假设我运行这段代码,以便从初始fork生成两个子进程。我会回来说它收获了第一个孩子。然而,一旦它第二次击中waitpid,它就会挂起,我永远也不会收到消息说它收获了第二个孩子。如果我产生四个子进程,那么可能会收获两个子进程,然后它将挂起。这是怎么回事?我必须对信号进行某种阻断吗?如果是这样,我应该在哪里阻止它?可能有一个孩子还没有退出,
waitpid()
正在等待。您应该在execvp()
之后添加一些错误代码,以防命令无法执行。如果不放置(最好)报告执行失败和退出的内容,可能会在您确实不想要它们的时候让您有多个进程在工作。您可能需要跟踪您创建的进程的PID,以便您可以等待它们显式退出,而不是等待一切完成。在适当的时候,您可能也会有后台作业(传统上,在管道的末尾运行&
)。然后,您不希望等待所有命令退出后再继续。如果您在处理SIGCHLD信号时遇到麻烦,则很容易造成混乱。粗略地说,不要!如果你没有摆弄SIGCHLD,你相信你正在使用的库不会摆弄它吗?标准C和POSIX库不会把你搞砸。你确定所有的孩子都离开了吗?使用ps
查看孩子们处于什么状态。感谢Jonathan和Barmar,事实证明waitpid()实际上工作正常。经过一些错误检查,我意识到进程实际上并没有退出。谢谢你的帮助!可能有一个子项尚未退出,waitpid()
正在等待。您应该在execvp()
之后添加一些错误代码,以防命令无法执行。如果不放置(最好)报告执行失败和退出的内容,可能会在您确实不想要它们的时候让您有多个进程在工作。您可能需要跟踪您创建的进程的PID,以便您可以等待它们显式退出,而不是等待一切完成。在适当的时候,您可能也会有后台作业(传统上,在管道的末尾运行&
)。然后,您不希望等待所有命令退出后再继续。如果您在处理SIGCHLD信号时遇到麻烦,则很容易造成混乱。粗略地说,不要!如果你没有摆弄SIGCHLD,你相信你正在使用的库不会摆弄它吗?标准C和POSIX库不会把你搞砸。你确定所有的孩子都离开了吗?使用ps
查看孩子们处于什么状态。感谢Jonathan和Barmar,事实证明waitpid()实际上工作正常。经过一些错误检查,我意识到进程实际上并没有退出。谢谢你的帮助!