注册处理信号后。在信号处理函数中,是否需要再次调用signal()来重新注册?
答案 0 :(得分:2)
检查this回答。或者特别是this链接。 基本上它取决于你的unix系统遵循的模型(BSD或System V)。
从信号手册页中提取。
在最初的Unix系统中,当通过传递信号调用使用signal()建立的处理程序时,将重置信号的处置 到SIG_DFL,系统没有阻止信号的进一步实例的传递。 System V还为signal()提供了这些语义。这很糟糕,因为 在处理程序有机会重新建立自己之前,可能会再次发送信号。此外,快速传递相同信号可能导致递归 调用处理程序。
BSD通过改变信号处理的语义改进了这种情况(但遗憾的是,在使用signal()建立处理程序时,默默地改变了语义)。在BSD上,当调用信号处理程序时,信号处理不会被重置,并且阻止信号的其他实例被传送。 处理程序正在执行。
Linux的情况如下:
- 内核的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语义。