GNU C 库参考手册 中有一个完整的章节详细讲解了关于信号处理的一切。
当你安装自己的信号处理程序时(参见 manpages 的 signal()
或 sigaction()
),你总是会得到先前设置的信号处理程序(一个函数指针)。
previous_handler = signal(SIGINT, myhandler);
通常的规则是,你可以始终重置到之前的处理程序并再次 raise()
信号。
void myhandler(int sig) {
signal(sig, previous_handler);
raise(sig);
signal(sig, myhandler);
}
一般规则有一个缺点:将映射到信号的硬件异常通常分配给导致异常的某个指令。因此,当您再次引发信号时,关联的指令不是最初的指令。这可能会但不应该影响其他信号处理程序。
另一个缺点是,每次引发信号都会消耗大量处理时间。为了防止过度使用raise()
,可以使用以下替代方法:
在SIG_DFL
情况下,函数指针指向地址0
(显然不是有效地址)。因此,您必须重置处理程序并再次raise()
信号。
if (previous_handler == SIG_DFL)
{
signal(sig, SIG_DFL);
raise(sig);
signal(sig, myhandler);
}
SIG_IGN
的值为1
(也是无效的地址)。在这里,您可以什么也不做(仅返回即可)。
else if (previous_handler == SIG_IGN)
{
return;
}
否则(既不是SIG_IGN
也不是SIG_DFL
),您已经收到一个有效的函数指针,可以直接调用处理程序。 else
{
previous_handler(sig);
}
当然,你也需要考虑不同的API(参见signal()
和sigaction()
的manpage)。
当然,您还需要考虑不同的API(请参阅signal()
和sigaction()
的man页面)。