sigaction - 为什么我们不需要重置处理程序?
如果我们使用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)
除非你指定的标志SA_RESETHAND
,性格没有改变(因此不需要重新设置)如果你是
设置sa.sa_flags = SA_RESETHAND
你需要重新设置,因为处置将被重置为SIG_DFL
(这是signal()
发生的情况)
基本上,您的问题的答案是“因为这就是sigaction的工作原理,它的行为与信号不同。
真正的原因可追溯到几十年前。原来的signal()
没有重装处理器。它也没有重启中断的系统调用。 BSD家伙决定有一个更“可靠”的signal()
,所以他们改变了这种语义。
由于System V和BSD行为如此不同,POSIX委托人决定引入一个新的系统调用sigaction()
,并带有参数来修改其行为。所以sigaction()
存在的全部原因是使用跨Unix变体表现相同的代码的信号。
(注意的signal()
的bahaviour可以改变使用相同的libc时,例如即使,glibc的默认使用BSD行为,SYSV行为定义_XOPEN_SOURCE时)。
当'_XOPEN_SOURCE'设置为一个非常旧的版本时,我希望它只使用SYSV行为,因为所有的现代版本都允许(更明智的)BSD行为,它应该被保留。 – 2011-03-14 02:22:20
感谢您了解新事物。 – kingsmasher1 2011-03-14 07:46:26
谢谢,非常好,信息丰富。 – kingsmasher1 2011-03-13 17:36:22