首页 > 解决方案 > 为什么 SIGINT 不止一次停止睡眠?

问题描述

我不明白为什么在第一次执行 kill 函数后 sleep 函数不会暂停父进程。发送 SIGINT 后,会生成许多进程。此外,似乎生成了可变数量的进程。从待处理信号中清除第一个 SIGINT 是否需要 SIGINT 处理程序?

void handler(int s) {
    int status;
    wait(&status);
    printf("\n in the handler");
    if (WIFSIGNALED(status)) {
        int sig=WTERMSIG(status);
        printf("\n child stopped by signal %d\n",sig);
    }
    if (WIFEXITED(status)) {
        int ex=WEXITSTATUS(status);
        printf("\n child stopped with exist status %d\n",ex);
    }
}

int main() {
    int pid,len, count, ret;
    char s[1024];
    signal(SIGCHLD,handler);
    while(1) {
        pid=fork();
        if (pid==0) {
            printf("\n Write something ");
            scanf("%s",s);
            len=strlen(s);
            printf("\n Characters: %d",len);
            return 1;
        }
        else {
            sleep(20);
            kill(pid,SIGINT);
        }
    }
}

标签: csleepkill

解决方案


就在您进入下一个时,上一个导致SIGCHLD儿童死亡的事件即将到来。killsleep

睡眠是一个可中断的功能。如果信号处理程序在您的线程中运行时运行,则将sleep中止。因此,您继续进行下一个kill,这将间接导致另一个SIGCHLD,这很可能在您的下一次迭代睡眠时发生,从而导致几个跳过的睡眠。

如果您插入sleep(1)before fork(),它应该(实际上)将时间转移到恰到好处,以便 nextsleep(20);不会中断。

(我将此视为一个快速而肮脏的实验。在生产代码中依赖这样的“调整”(或printf在信号处理程序中使用)绝不是一个好主意。)


推荐阅读