为什么SIGINT会多次停止睡眠?

时间:2019-05-08 16:24:54

标签: c sleep kill

我不明白为什么在第一次执行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);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

上一个导致儿童死亡的SIGCHLD中的kill恰好在您进入下一个sleep时才到达。

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

如果在sleep(1)之前插入fork(),它应(实际上)将定时恰好移至下一个sleep(20);不间断。

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