使用signal()
或者最好是sigaction()
,我们可以选择忽略或显式处理大多数POSIX信号。例如,为了忽略SIGCHLD
我们可以执行以下操作:
struct sigaction sa_chld = { .sa_handler = SIG_IGN };
sigaction(SIGCHLD, &sa_chld, NULL);
有没有办法弄清楚给定的信号是否被程序忽略和/或捕获?
理想情况下,我想区分信号是否...
- 正在按照默认操作进行处理
- 被显式忽略
- 被显式捕获
对于正在运行的进程,您可以签出/proc/PID/status
并分别检查字段SigBlk
、SigIgn
和SigCgt
是否有阻塞、忽略和捕获的信号。
有人编写了一个方便"解码"它的实用程序脚本,我个人认为它非常有用并一直在使用它。
有关详细信息和更多相关字段,请参阅proc
文档。
是的。
例:
#include <signal.h>
#include <stdio.h>
void h(int Sig){(void)Sig; }
int main()
{
signal(1,SIG_IGN); //note: setting ign/dfl is more compat (and still safe) with signal()
sigaction(2, &(struct sigaction){.sa_handler=h},0);
for(int i=1; i<8; i++){
struct sigaction oldsa;
sigaction(i, 0, &oldsa);
if(!(oldsa.sa_flags&SA_SIGINFO)){
if(oldsa.sa_handler==SIG_IGN) printf("%d ignoredn", i);
else if(oldsa.sa_handler==SIG_DFL) printf("%d defaultedn", i);
else goto caught;
}else caught:
printf("%d caughtn", i);
}
}
示例输出:
1 ignored
2 caught
3 defaulted
4 defaulted
5 defaulted
6 defaulted
7 defaulted
在 Linux 上不可移植,您还可以解析/proc/$PID/stat
(或具有人类可读版本的status
(以查看信号是否在进程的捕获/忽略掩码中 (if(mask&(1ul<<(signalnumber-1)) printf("%d in the mask", signalnumber);
(。
Linux 将捕获/忽略的信号列表作为位掩码维护,但 POSIX 不会公开这些信号,而是要求您通过对sigaction
的非设置调用单独获取每个单独的处置。