c - 父进程不会使用 signal() 等待所有子进程退出

标签 c signals fork sleep sigchld

程序最初要求用户输入要创建的子进程的数量。创建子级后,父级将休眠并等待其所有子级通过向 SIGCHLD 注册的信号处理函数“handle_child”终止。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

int to_kill;

void handle_child(int sig)
{
    pid_t id = wait(NULL);
    printf("Reaped child with PID = %d\n",id);
    --to_kill;
    if(to_kill == 0){
        printf("~All children have been reaped successfully.. parent will now exit~\n");
        exit(0);
    }
}

int main()
{
    pid_t id, parent_id = getpid();
    int children, i;
    signal(SIGCHLD, handle_child);
    printf("Enter number of child processes to spawn: ");
    scanf("%d",&children);
    to_kill = children;
    for(i = 0; i < children; ++i){
        id = fork();
        if(id == 0){
            printf("New child with pid = %d\n",getpid());
            sleep(2);
            return 0;
        }
        sleep(1);
    }
    sleep(30);
    return 0;
}

我面临的问题是父进程经常退出而没有收获所有的子进程。有时程序运行得很好,有时却突然结束。这里到底发生了什么?

错误输出的实例之一:

Enter number of child processes to spawn: 4
New child with pid = 6458
New child with pid = 6459
Reaped child with PID = 6458
New child with pid = 6461
Reaped child with PID = 6459
New child with pid = 6462
Reaped child with PID = 6461
nishad@nishad-Lenovo-B575:~$

最佳答案

我认为对 sleep(30) 的调用被 SIGCHLD 中断中断,因此它不会休眠 30 秒,而是在调用信号处理程序后立即返回。

为了得到正确的结果,你需要循环 sleep :

tosleep = 30;
while (tosleep > 0) {
    tosleep = sleep(tosleep);
}

关于c - 父进程不会使用 signal() 等待所有子进程退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29600481/

相关文章:

c - 这两个带有递归函数和静态变量的C程序谁有不同的输出?

c - 信号在 Linux 上如何工作(c)?

c++ - prctl(PR_SET_PDEATHSIG, SIGNAL) 在父线程退出时调用,而不是在父进程退出时调用

C:为什么我们要包含头文件,声明但不定义?

c - 如何通过预处理器运行 diff 文件来获取常量值

Python 3 的 Signal.sigwaitinfo 与 Python 2.7 等效吗?

unix - 父进程和子进程是否具有相同的堆栈

linux - fork 似乎在不必要的时候进行复制

C 使用数组值删除数组

c - sigprocmask() 中的 Set 和 Oldset