在C、linux中,关于循环中的kill信号和sleep()

Wei*_* Li 1 c linux macos signals kill

我在 Mac OS 上运行 C 程序。我的程序的一部分如下。此代码在 sigint 信号上运行良好,但无法在 sigkill 信号上运行。

void sigkill(int sig){
    /*some code neglected*/
    exit(0);
}
void sigint(int sig){
    flag=1;
}

void alive(void) {
    signal(SIGINT, sigint);
    signal(SIGKILL, sigkill);
    alarm(10);
    while(1){
        //printf("%d\n",flag);
        sleep(1);
        if(flag==1){
            printf("no\n");
            flag=0;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我有四个问题:

  1. 起初我没有写sleep(1),它可以进入函数sigint(),并改变标志值,我从printf中可以看到。然而,没有像我预期的那样输出“no”。

  2. 添加睡眠功能后,效果很好。我想 while 循环会每 1 秒检查一次 flag,如果 flag=1 则输出“no”。但是,每次按 ctrl+c 时似乎都会输出“no”。为什么连一秒钟都不等?

  3. 问题是“你不应该使用'sleep()'来等待10秒。使用alarm(),加上一个循环。” 我想知道如何在没有 sleep() 的情况下实现这一点。

  4. Kill 命令无法调用 sigkill 函数,如何解决这个问题?

J E*_*rls 5

  1. 一般来说,只有当应用程序对内核进行系统调用时,信号才能被应用程序“捕获”。如果您执行 plain 操作while(1) { if (flag==1){...} },则永远不会调用内核。printf理论上,当您在循环中执行外部操作时while(1),应该调用内核,以便可以捕获信号。
  2. sleep()被任何信号中断。检查 的手册页sleep(3)
  3. 检查 的手册页alarm(2)
  4. SIGKILL您不能更改或 的信号处理程序SIGSTOP。这些信号效果被硬编码到内核中。从sigaction(2)

    Signum指定信号,可以是除SIGKILL和之外的任何有效信号SIGSTOP

    不带参数的命令kill不会生成SIGKILL信号;它生成SIGTERM.