如果我们使用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)
真正的原因可以追溯到几十年前.原件signal()没有重新装配处理器.它也没有重启中断的系统调用.BSD家伙决定更"可靠" signal(),所以他们改变了语义.
由于System V和BSD行为如此不同,POSIX委员会决定引入一个新的系统调用sigaction(),并使用参数来修改其行为.所以sigaction()存在的全部原因是使用在Unix变体中行为相同的代码来获取信号.
(注意,即使使用相同的libc,bahaviour signal()也会改变,例如,glibc默认使用BSD行为,定义_XOPEN_SOURCE时使用SYSV行为).
除非您SA_RESETHAND在标志中指定,否则不会更改处置(因此不需要重置)
如果您要设置sa.sa_flags = SA_RESETHAND您需要重置它,因为处置将被重置为SIG_DFL(这是发生的事情signal())
基本上,你的问题的答案是"因为这是sigaction如何工作.它的行为不同于信号".