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

kin*_*er1 2 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)
Run Code Online (Sandbox Code Playgroud)

nin*_*alj 6

真正的原因可以追溯到几十年前.原件signal()没有重新装配处理器.它也没有重启中断的系统调用.BSD家伙决定更"可靠" signal(),所以他们改变了语义.

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

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


Bri*_*ach 5

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

如果您要设置sa.sa_flags = SA_RESETHAND您需要重置它,因为处置将被重置为SIG_DFL(这是发生的事情signal())

基本上,你的问题的答案是"因为这是sigaction如何工作.它的行为不同于信号".