sighandler中的第二个信号呼叫 – 为什么?

最近我发现了一些使用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 } 

我有一些麻烦要弄清楚为什么我需要拨打2次signal ,尤其是为什么我需要在sighandler调用signal ? 我知道上面的代码做了什么,但不明白为什么我需要调用signal 2次。

处理信号

信号呼叫仅为一次信号发生信号处理。 在调用信号处理function之前, 库会重置信号,以便在再次出现相同信号时执行默认操作 。 例如,如果在信号处理程序中执行的动作再次引发相同的信号,则重置信号处理有助于防止无限循环。 如果您希望每次发生时都将处理程序用于信号,则必须在处理程序中调用signal来恢复它。 您应该谨慎恢复信号处理。 例如,如果您不断恢复SIGINT处理,则可能会失去中断和终止程序的能力。

signal()函数仅定义下一个接收信号的处理, 之后恢复默认处理 。 因此,如果程序需要使用非默认处理程序继续处理信号,则信号处理程序必须调用signal()

(1)两次或多次呼叫signal并不罕见。 它只是为2个不同的信号设置了两个处理程序。

(2)较旧的unix系统用于在调用处理程序后将信号处置重置为默认值。 此代码正在重新建立处理程序。

GNU man (2) signal页面在“可移植性”部分有两个专门用于此的段落。 实际上是使用sigaction的几个原因之一。

有些系统,如果用函数调用signal() ,信号处理程序在第一个信号被捕获后被重置为默认值(如果定义为这样,我还没有发现它)。 这就是为什么在信号处理程序中再次调用signal()的原因。