信号 - C99 VS gnu99 [英] Signals - c99 vs gnu99

查看:1885
本文介绍了信号 - C99 VS gnu99的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code。当我用GNU扩展( -std = gnu99 )编译,程序会结束(这是我所期望的)前赶5 SIGINT。如果没有它( -std = C99 )编译后的第二个结束(和只输出一行)。

我是什么失踪?

 的#include<&signal.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;INT int_stage = 0;
INT got_signal = 0;无效SIGINT(INT参数)
{
  (无效)参数;
  got_signal = 1;
  int_stage ++;
}诠释的main()
{
  信号(SIGINT,SIGINT);  而(1)
  {
    如果(got_signal)
    {
      got_signal = 0;
      看跌期权(还活着);
      如果(int_stage> = 5)出口(1);
    }
  }
  返回0;
}


解决方案

使用<一个href=\"http://www.kernel.org/doc/man-pages/online/pages/man2/sigaction.2.html\"><$c$c>sigaction(2)而不是<一href=\"http://www.kernel.org/doc/man-pages/online/pages/man2/signal.2.html\"><$c$c>signal(2).

Linux手册页有这个,特别是在流通部分:


  

在原来的UNIX系统中,当使用信号()建立一个处理程序被调用的
         的信号的传送中,信号的配置将被重置为SIG_DFL,系统做
         不阻挡信号的进一步实例的递送。系统V还提供了这些语义
         信号()。这是不好的,因为信号可能会被再次交付的处理程序有机会之前
         重建本身。此外,同样的信号的快速运送可能导致递归
         处理程序的调用。


  
  

BSD通过改变信号处理的语义在此形势有所好转(但不幸的是,
         建立与信号处理程序时,默默地改变了语义())。在BSD,当信号
         调用处理程序时,信号处置不复位,并且信号的进一步实例是
         封锁而处理程序执行交付。


  
  

在Linux上的情况如下:


  
  

      
  • 内核的信号()系统调用提供系统V语义。


  •   
  • 默认情况下,glibc的2和更高版本,信号()包装函数不会调用系统内核
           呼叫。相反,它使用该供应BSD的语义标记调用的sigaction(2)。此默认behav-
           作为_BSD_SOURCE功能测试宏定义IOR提供一样长。缺省情况下,_BSD_SOURCE
           被定义为;它也被隐含定义,如果一个限定_GNU_SOURCE,并且当然可以explic-
           itly定义。结果
           在glibc的2和更高版本,如果没有定义_BSD_SOURCE功能测试宏,然后信号()提供
           System V的语义。 (_BSD_SOURCE的默认隐含定义不如果一个中提供
           在标准模式之一(-std = XXX或-ansi)或定义了各种其他功能调用GCC(1)
           测试宏如_POSIX_SOURCE,_XOPEN_SOURCE或_SVID_SOURCE;看到feature_test_macros(7)。)


  •   

使用 STD = gnu99 ,你得到BSD的语义。使用 -std = C99 ,你得到System V的语义。因此信号处理程序在一种情况下(BSD)的重新安装,并且信号处置在其它(系统V)重置为SIG_DFL

I have the following code. When I compile it with the gnu extensions (-std=gnu99), the program will catch 5 SIGINT before ending (which I would expect). When compiled without it (-std=c99) ends after the second (and only outputs one line).

What am I missing?

#include <signal.h>
#include <stdlib.h>
#include <stdio.h>

int int_stage = 0;
int got_signal = 0;

void sigint(int parameter)
{
  (void)parameter;
  got_signal = 1;
  int_stage++;
}

int main()
{
  signal(SIGINT,sigint);

  while(1)
  {
    if (got_signal)
    {
      got_signal = 0;
      puts("still alive");
      if (int_stage >= 5) exit(1);
    }
  }
  return 0;
}

解决方案

Use sigaction(2) rather than signal(2).

The Linux man page has this, in particular, in the Portability section:

In the original UNIX systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal. System V also provides these semantics for signal(). This was bad because the signal might be delivered again before the handler had a chance to reestablish itself. Furthermore, rapid deliveries of the same signal could result in recursive invocations of the handler.

BSD improved on this situation by changing the semantics of signal handling (but, unfortunately, silently changed the semantics when establishing a handler with signal()). On BSD, when a signal handler is invoked, the signal disposition is not reset, and further instances of the signal are blocked from being delivered while the handler is executing.

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 behav‐ ior is provided 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 explic‐ itly 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).)

Using std=gnu99, you're getting BSD semantics. Using -std=c99, you're getting System V semantics. So the signal handler is "reinstalled" in one case (BSD), and the signal disposition is reset back to SIG_DFL in the other (System V).

这篇关于信号 - C99 VS gnu99的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆