sigaction - 为什么我们不必重置处理程序?

时间:2011-03-13 16:02:18

标签: c unix signals

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

#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:
[root@dhcppc0 signals]# ./a.out
     caught signal:34
     caught signal:34
     caught signal:34 (3 times signal caught by same handler without resetting handler)

2 个答案:

答案 0 :(得分:6)

真正的原因可以追溯到几十年前。原始signal()没有重新安装处理程序。它也没有重启中断的系统调用。 BSD家伙决定拥有更“可靠”的signal(),因此他们改变了语义。

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

(注意signal()的bahaviour在使用相同的libc时可以更改甚至,例如,glibc默认使用BSD行为,定义_XOPEN_SOURCE时使用SYSV行为。 / p>

答案 1 :(得分:5)

除非您在标志中指定SA_RESETHAND,否则处置不会更改(因此不需要重置)

如果您要设置sa.sa_flags = SA_RESETHAND您需要重置它,因为处理方式会重置为SIG_DFLsignal()会发生这种情况)

基本上,你的问题的答案是“因为这就是sigaction如何运作。它的行为与信号不同”。