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

标签 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)

最佳答案

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

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

(请注意,即使使用相同的 libc,signal() 的行为也会发生变化,例如,glibc 默认使用 BSD 行为,定义 _XOPEN_SOURCE 时使用 SYSV 行为)。

关于c - sigaction - 为什么我们不必重置处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5290540/

相关文章:

python - 在 UNIX shell 中捕获 Python 进程的退出状态

linux - 信号处理的安全全局状态

python - 一个接一个地计算多个正弦波

go - 是否可以只记录收到的每个信号而不改变行为?

使用相同的输入文件多次调用 yyparse()

c# - 如何编码双指针?

c - Eclipse - 构建与重建(makefile C 项目)

unix - 在 unix 中用另一个序列替换字符串模式

linux - 在 Unix 中比较两个大文件

C 预处理器宏