捕获 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()
.
的原因
我有一些用 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()
.