如果我们使用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)
答案 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_DFL
(signal()
会发生这种情况)
基本上,你的问题的答案是“因为这就是sigaction如何运作。它的行为与信号不同”。