Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么waitpid挂起而不是获取所有子进程?_C_Operating System_System_System Calls_Waitpid - Fatal编程技术网

C 为什么waitpid挂起而不是获取所有子进程?

C 为什么waitpid挂起而不是获取所有子进程?,c,operating-system,system,system-calls,waitpid,C,Operating System,System,System Calls,Waitpid,我试图模拟shell处理前台命令,但在获取子进程时遇到了麻烦。我在下面的代码中使用fork生成多个进程 while (currCmdListNode != list_end(&currentPipeline->commands)) { if (fork() == 0) { printf("Child created with pid %d \n", getpid());

我试图模拟shell处理前台命令,但在获取子进程时遇到了麻烦。我在下面的代码中使用fork生成多个进程

while (currCmdListNode != list_end(&currentPipeline->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(&currentPipeline->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()实际上工作正常。经过一些错误检查,我意识到进程实际上并没有退出。谢谢你的帮助!