我编写了一个应用程序,其中我为 linux 中的不同信号注册了多个信号处理程序。
进程接收到信号后,控制权将转移到我注册的信号处理程序。在这个信号处理程序中,我做了一些我需要做的工作,然后我想调用默认信号处理程序,即SIF_DFL
or SIG_IGN
。
然而,SIG_DFL
and SIG_ING
都是分别扩展为数值 0 和 1 的宏,它们是无效的函数地址。
有什么方法可以调用默认操作,即SIG_DFL
or SIG_IGN
?
为了达到这样的效果SIG_DFL
or SIG_ING
我分别调用 exit(1) 和不执行任何操作。但对于像这样的信号SIGSEGV
我也想要核心转储。
一般来说,我希望我的默认行为与SIG_DFL
并忽略相同的行为SIG_IGN
,就像操作系统所做的那样。
GNU C 库参考手册 http://www.gnu.org/software/libc/manual/html_node/Signal-Handling.html有整整一章解释了有关信号处理的所有内容。
当您安装自己的处理程序时,您总是会获得先前设置的信号处理程序(函数指针)(请参阅手册页signal()
or sigaction()
).
previous_handler = signal(SIGINT, myhandler);
一般规则是,您始终可以重置到以前的处理程序并raise()
再次发出信号。
void myhandler(int sig) {
/* own stuff .. */
signal(sig, previous_handler);
raise(sig);
/* when it returns here .. set our signal handler again */
signal(sig, myhandler);
}
有一个坏处一般规则:映射到信号的硬件异常通常被分配给导致异常的特定指令。因此,当您再次发出信号时,相关指令与原来的指令不同。这可能但不应该损害其他信号处理程序。
Another 坏处也就是说,每个升高的信号都会导致大量的处理时间。为防止过度使用raise()
您可以使用以下替代方案:
-
的情况下SIG_DFL
函数指针指向地址0
(这显然不是有效的地址)。这样,你have to重置处理程序并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
nor SIG_DFL
)你已经收到一个有效的函数指针并且你can直接调用处理程序,
else
{
previous_handler(sig);
}
当然,您还必须考虑不同的 API(请参阅手册页signal()
and sigaction()
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)