2011-03-13 69 views
2

如果我们使用sigaction来定义信号处理程序,那么为什么我们不需要重置处理程序?如果我们使用signal(sig_no,handler_func)那么我们必须重置它。为什么是这样?sigaction - 为什么我们不需要重置处理程序?

#include <unistd.h> 
#include <stdio.h> 
#include <signal.h> 

void func(int sig) 
{ 
printf("caught signal:%d\n",sig); 
// Not needed to reset handler. Why? 
} 

int main() 
{ 
struct sigaction sa; 

sa.sa_handler=(void*)func; 
sigaction(SIGRTMIN,&sa,NULL); 
kill(0,SIGRTMIN); 
kill(0,SIGRTMIN); 
kill(0,SIGRTMIN); 
} 
Output: 
[[email protected] signals]# ./a.out 
    caught signal:34 
    caught signal:34 
    caught signal:34 (3 times signal caught by same handler without resetting handler) 

回答

5

除非你指定的标志SA_RESETHAND,性格没有改变(因此不需要重新设置)如果你是

设置sa.sa_flags = SA_RESETHAND你需要重新设置,因为处置将被重置为SIG_DFL(这是signal()发生的情况)

基本上,您的问题的答案是“因为这就是sigaction的工作原理,它的行为与信号不同。

+0

谢谢,非常好,信息丰富。 – kingsmasher1 2011-03-13 17:36:22

6

真正的原因可追溯到几十年前。原来的signal()没有重装处理器。它也没有重启中断的系统调用。 BSD家伙决定有一个更“可靠”的signal(),所以他们改变了这种语义。

由于System V和BSD行为如此不同,POSIX委托人决定引入一个新的系统调用sigaction(),并带有参数来修改其行为。所以sigaction()存在的全部原因是使用跨Unix变体表现相同的代码的信号。

(注意的signal()的bahaviour可以改变使用相同的libc时,例如即使,glibc的默认使用BSD行为,SYSV行为定义_XOPEN_SOURCE时)。

+0

当'_XOPEN_SOURCE'设置为一个非常旧的版本时,我希望它只使用SYSV行为,因为所有的现代版本都允许(更明智的)BSD行为,它应该被保留。 – 2011-03-14 02:22:20

+0

感谢您了解新事物。 – kingsmasher1 2011-03-14 07:46:26

相关问题