最近我发现了一些使用signal
的代码:
286 static void sighandler( int signum )
287 {
288 alarmed = 1;
289 signal( signum, sighandler );
290 }
291
292 void set_alarm( int seconds )
293 {
294 alarmed = 0;
295 signal( SIGALRM, sighandler );
296 alarm( seconds );
297 }
我有一些麻烦要弄清楚为什么我需要拨打signal
2次,尤其是为什么我需要在signal
中拨打sighandler
?我知道上面的代码做了什么,但不明白为什么我需要调用signal
2次。
答案 0 :(得分:2)
(1)拨打signal
两次或更多次并不罕见。它只是为两个不同的信号设置了两个处理程序。
(2)较旧的unix系统用于在调用处理程序后将信号处置重置为默认值。此代码正在重新建立处理程序。
The GNU man (2) signal
page在“可移植性”部分中有几段专门讨论这个问题。实际上是使用sigaction
的几个原因之一。
答案 1 :(得分:2)
信号呼叫建立信号处理仅发生一次信号。在调用信号处理功能之前,库会重置信号,以便在再次出现相同信号时执行默认操作。例如,如果在信号处理程序中执行的动作再次引发相同的信号,则重置信号处理有助于防止无限循环。如果希望每次出现处理程序时都使用处理程序,则必须在处理程序中调用signal来恢复它。您应该谨慎恢复信号处理。例如,如果您不断恢复SIGINT处理,则可能会失去中断和终止程序的能力。
signal()
函数仅定义下一个接收信号的处理,之后恢复默认处理。因此,如果程序需要使用非默认处理程序继续处理信号,则信号处理程序必须调用signal()
。
答案 2 :(得分:1)
有些系统,如果用函数调用signal()
,信号处理程序会在第一个信号被捕获后被重置为默认值(如果它没有被发现,我就不会发现它)'定义为如此)。这就是为什么在信号处理程序中再次调用signal()
的原因。