问题描述
注册后处理信号.在信号处理函数中是否需要再次调用signal()重新注册?
After registering to handle a signal. In the signal handler function is it necessary to call signal() again to re-register?
推荐答案
检查这个答案.或者特别是这个链接.基本上,这取决于您的 Unix 系统遵循的模型(BSD 或 System V).
Check this answer. Or particularly this link.Basically it depends on the model (BSD or System V) your unix system follows.
摘自信号手册页.
在原始的 Unix 系统中,当通过信号的传递调用使用 signal() 建立的处理程序时,信号的处置将被重置到 SIG_DFL,并且系统没有阻止信号的其他实例的传递.System V 还为 signal() 提供了这些语义.这很糟糕,因为信号可能会在处理程序有机会重新建立之前再次传递.此外,相同信号的快速传递可能导致递归处理程序的调用.
BSD 通过更改信号处理的语义来改善这种情况(但不幸的是,在使用 signal() 建立处理程序时,它悄悄地更改了语义).在 BSD 上,当信号处理程序被调用时,信号处置不会被重置,并且信号的更多实例被阻止传递,同时处理程序正在执行.
BSD improved on this situation by changing the semantics of signal handling (but, unfortunately, silently changed the semantics when establishing a handler with signal()). On BSD, when a signal handler is invoked, the signal disposition is not reset, and further instances of the signal are blocked from being delivered while the handler is executing.
Linux 上的情况如下:
The situation on Linux is as follows:
- 内核的 signal() 系统调用提供 System V 语义.
- 默认情况下,在 glibc 2 及更高版本中,signal() 包装函数不调用内核系统调用.相反,它使用提供 BSD 语义的标志调用 sigaction(2).只要定义了 _BSD_SOURCE 功能测试宏,就会提供此默认行为.默认情况下,_BSD_SOURCE 已定义;如果定义了 _GNU_SOURCE,它也是隐式定义的,当然也可以显式定义.
在 glibc 2 及更高版本上,如果未定义 _BSD_SOURCE 功能测试宏,则 signal() 提供 System V 语义.(如果以一种标准模式(-std=xxx 或 -ansi)调用 gcc(1) 或定义各种其他功能测试宏,例如 _POSIX_SOURCE、_XOPEN_SOURCE 或 _SVID_SOURCE,则不提供 _BSD_SOURCE 的默认隐式定义;请参阅 feature_test_macros(7).) - Linux libc4 和 libc5 中的 signal() 函数提供 System V 语义.如果 libc5 系统上的一个包含而不是 ,则 signal() 提供 BSD 语义.
这篇关于UNIX 中的信号处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!