捕获 SIGTERM,并睡眠阻止它工作

Catching SIGTERM, and sleep preventing it working

我有一些用 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 函数,有没有更好的方法来 "sleep" 程序”,以便它只每 x 分钟运行一次循环,或者以最小化的方式CPU 负载?

sleep() 和信号

sleep() 不应阻止信号被捕获和信号处理程序被执行。来自 manpage for sleep()(强调我的):

sleep() causes the calling thread to sleep either until the number of real-time seconds specified in seconds have elapsed or until a signal arrives which is not ignored.

举下面的例子...

#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() returns 剩余休眠秒数。例如,如果提前 3 秒被打断,它将 return 3。不打断就会return0

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

pkill -15 test

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

Sleeping at time 1532273709
Flag raised. Exiting at time 1532273711. sleep() was interrupted 2 seconds early ...

顺便说一下……sleep(x)x - 而不是分钟。

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().

的原因