【问题标题】:In C, linux, about kill signal and sleep() in loop在 C、linux 中,关于循环中的 kill 信号和 sleep()
【发布时间】:2017-01-13 06:46:18
【问题描述】:

我在 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;
        }
    }
}

我有四个问题:

  1. 一开始我没有写sleep(1),可以进入函数sigint(),改变flag值,从printf中可以看出。但是,没有我预期的“否”输出。

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

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

  4. kill命令无法调用sigkill函数,如何解决?

【问题讨论】:

  • 你不能陷进去SIGKILL——句号。您不能为SIGKILL 设置陷阱。顺便提一下SIGSTOP
  • 你知道不用sleep()怎么实现吗?
  • 混合使用 alarm()sleep() 并不是 100% 可靠的。您可以使用alarm()pause()pause() 仅在中断且信号处理程序返回时返回。您可以使用select()poll() 以及特定于平台的变体进行亚秒级睡眠。您可以使用nanosleep()usleep() 进行纳秒和微秒分辨率的休眠(尽管精度通常不如分辨率)。如果你仔细看,某处可能有一毫秒的睡眠时间。
  • 谢谢,你说得对!

标签: c linux macos signals kill


【解决方案1】:
  1. 一般来说,只有当应用程序对内核进行系统调用时,信号才能被“捕获”。如果你做一个普​​通的while(1) { if (flag==1){...} },那将永远不会调用内核。从理论上讲,当您在 while(1) 循环中执行外部 printf 时,应该调用内核,因此可以捕获信号。
  2. sleep() 被任何信号打断。查看sleep(3) 的手册页。
  3. 查看alarm(2) 的手册页。
  4. 您不能更改SIGKILLSIGSTOP 的信号处理程序。这些信号效果被硬编码到内核中。来自sigaction(2)

    signum 指定信号,可以是除SIGKILLSIGSTOP 之外的任何有效信号。

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

【讨论】:

  • 我不是很明白第三个答案。不睡觉怎么实现?
  • 来自alarm(2) 的手册页:alarm() arranges for a SIGALRM signal to be delivered to the process in seconds seconds.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-29
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多