signal函数和sigactiion函数的对比

在《UNIX环境高级编程》中,作者写道:从UNIX System V派生的实现支持signal函数,但该函数提供旧的不可靠的语义,4.4BSD也提供signal函数,但它是按照sigaction函数定义的,所以在4.4BSD之下使用它提供新的可靠信号语义,目前大多数系统遵循这种策略。

在该书10.4节,作者举了两个不可靠信号的例子。一是如下代码,目的是不要调用一次信号处理函数之后就回到默认动作,而是一直使用该信号处理函数处理信号。但是问题是,在信号发生之后到信号处理程序调用signal之间的时间窗内有可能再次发生信号,第二次发生的信号会执行默认动作而不是注册的信号处理函数。

int sig_int();
...
signal(SIG_INT_, sig_int);
...
sig_int()
{
<span style="white-space:pre">	</span>signal(SIG_INT, sig_int);
<span style="white-space:pre">	</span>...
}

二是进程无法关闭信号而只能忽略它,使用标志位来处理,代码格式如下。但是在测试标志位和调用pause()的时间窗中,发生信号的话就会造成pause()永久休眠,因此也是不可靠的。

int sig_int();
int sig_int_flag;
main()
{
    signal(SIGINT, sig_int);
    ...
    while(sig_int_flag == 0)
        pause();
    ...
}

sig_int()
{
    signal(SIGINT, sig_int);
    sig_int_flag = 1;
}

而sigaction可以避免这个问题,因而是可靠的。一般都建议使用sigaction()来代替signal函数。而实际在linux中,signal()库函数就是用sigaction()实现的。当然,signal()系统调用并不是这样,存在缺陷。在Linux终端man signal,有如下一段:

The situation on Linux is as follows:


       * The kernel's signal() system call provides System V semantics.


       * By default, in glibc 2 and later, the signal() wrapper function  does

         not  invoke  the  kernel system call.  Instead, it calls sigaction(2)

         using flags that supply BSD semantics.  This default behavior is pro‐

         vided  as  long as the _BSD_SOURCE feature test macro is defined.  By

         default, _BSD_SOURCE is defined; it is also implicitly defined if one

         defines _GNU_SOURCE, and can of course be explicitly defined.


         On  glibc  2  and later, if the _BSD_SOURCE feature test macro is not

         defined, then signal() provides System  V  semantics.   (The  default

         implicit  definition  of  _BSD_SOURCE  is not provided if one invokes

         gcc(1) in one of its standard modes (-std=xxx or  -ansi)  or  defines

         various   other   feature   test   macros   such   as  _POSIX_SOURCE,

         _XOPEN_SOURCE, or _SVID_SOURCE; see feature_test_macros(7).)


       * The signal() function in Linux  libc4  and  libc5  provide  System  V

         semantics.   If one on a libc5 system includes <bsd/signal.h> instead

         of <signal.h>, then signal() provides BSD semantics.

而且,现在的Linux版本一般都默认定义了_BSD_SOURCE,因此,一般情况下直接使用signal()不会存在问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值