捕捉SIGTERM,并入睡以防其工作

时间:2018-07-22 11:06:23

标签: c sigterm

我有一些用C编写的代码(在ubuntu 17上工作):

void sig_stop(int sig_num) {
    /* Some cleanup that needs to be done */
}

void some_routine(const char *array[], const int length) {
    /* Initialization */
    signal(SIGTERM, sig_stop);

    while (true) {
        /* Some function */

        /* I have this sleep to minimize the load on the CPU 
            as I don't need to check the conditions here 
            all the time. */
        sleep(5);
    }
}

每当我包括5分钟的睡眠(sleep(5))时,似乎都没有呼叫sig_stop。但是,当我注释掉sleep(5)时,sig_stop清理工作正常。我对如何捉住SIGTERM有什么误解吗?

如果我不能使用sleep函数,是否有更好的方法“休眠”程序”,使其仅每x分钟运行一次循环或以最小化CPU负载的方式运行?

1 个答案:

答案 0 :(得分:3)

sleep()和信号

sleep()不应阻止捕获信号和执行信号处理程序。来自manpage for sleep()(重点是我):

  

sleep()使调用线程进入睡眠状态,直到经过以秒为单位指定的实时秒数为止,或者直到信号到来而未被忽略

以下面的示例为例...

#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>

static volatile sig_atomic_t flag = 0;

static void sig_stop(int signum) { flag = 1; }

int main(void) {
    int secs_remaining = 0;
    signal(SIGTERM, sig_stop);

    while (!flag) {
        printf("Sleeping at time %d\n", time(NULL));
        secs_remaining = sleep(5);
    }
    printf(
        "Flag raised. Exiting at time %d. sleep() was interrupted %d seconds "
        "early ...\n",
        time(NULL), secs_remaining);

    return 0;
}

请注意-在信号中断的情况下-sleep()返回剩余的睡眠秒数。例如,如果提前3秒钟中断,它将返回3。如果没有中断,它将返回0

编译为gcc -o test test.c并运行。然后从另一个终端运行

pkill -15 test

您将看到类似于以下内容的输出...

  

在时间1532273709睡觉
  升起的旗帜。在1532273711时间退出。sleep()提前2秒被中断了...

顺便说一下,sleep(x)睡眠了x秒(ems)-而不是分钟。

signal()sigaction()

由于与signal()相关的可移植性问题,通常建议改用sigaction()sigaction()的使用将类似于以下内容。

int main(void) {
    struct sigaction sa;

    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sa.sa_handler = sig_stop;
    if (sigaction(SIGTERM, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }
    // Etc.
}

如您所见,sigaction()的用法比signal()的用法更为冗长。也许这就是为什么人们有时仍然使用signal()的原因。