首页 > 解决方案 > 忽略信号是什么意思?

问题描述

信号被忽略是什么意思?

标签: signals

解决方案


Linux 中的信号处理是使用 glibc 系统调用库“在幕后”完成的。根据gnu 库文档

SIGTERM 信号是用于导致程序终止的通用信号。与 SIGKILL 不同,此信号可以被阻止、处理和忽略。这是礼貌地要求程序终止的正常方式。

我将尝试在下面定义术语被阻止处理忽略(代码示例不包括错误处理,因此请注意):

Blocked:在 Linux 中运行的每个进程在进程创建时都会被赋予一个信号掩码。sigprocmask函数调用可用于阻塞或解除阻塞信号 - 阻塞信号被排队,以便稍后在进程解除阻塞时对其进行处理。例如,使用与标准信号相关的系统调用(来自 The Linux Programming Interface,Michael Kerrisk)来阻止 SIGTERM -

    sigset_t blockSet, savedSigMask;
    sigemptyset(&blockSet); /* initialize empty */
    sigaddset(&blockSet, SIGTERM);
    sigprocmask(SIG_BLOCK, &blockSet, &savedSigMask);

/* process will not be interrupted by SIGTERM, which can be restored later*/

Ignored:类似地,可以使用 sigaction 系统调用和 SIG_IGN 标志来忽略信号 - 即进程在接收到信号时不会被中断,并且信号不会被排队 - 通过使用系统调用sigaction

struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NODEFER; /* Dont block the signal when it's handler is running */
sigaction(SIGTERM, &sa, NULL);

Handled : sigaction 也可用于定义接收信号时调用的函数。这是接收 SIGTERM 的最佳实践,允许您的进程优雅地关闭。

struct sigaction sa;
sa.sa_sigaction = functionp; /* functionp is your handler function */
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NODEFER | SA_SIGINFO;
sigaction(signo, &sa, NULL; 

您可以为 SIGTERM 使用信号处理程序,这样它就不会导致您的进程退出,但这通常不是 SIGTERM 处理程序的用途。另一件需要注意的事情是,在运行systemd的系统上,systemd 将向接收到 SIGTERM 然后不退出的程序发送 KILL 信号,因此必须将 systemd 配置为允许您的进程忽略 SIGTERM。


推荐阅读