c - 执行默认信号处理程序

标签 c linux signals handlers

我编写了一个应用程序,我在其中为 linux 中的不同信号注册了多个信号处理程序。 进程收到信号后,控制权将转移到我注册的信号处理程序。在这个信号处理程序中,我做了一些我需要做的工作,然后我想调用默认信号处理程序,即 SIF_DFLSIG_IGN 。 但是,SIG_DFLSIG_ING都是宏,分别扩展为数值0和1,是无效的函数地址。

有什么方法可以调用默认操作,即 SIG_DFLSIG_IGN 吗?

为了实现 SIG_DFLSIG_ING 的效果,我分别调用了 exit(1) 并且什么都不做。但是对于像 SIGSEGV 这样的信号,我也希望有 core dump 。 一般来说,我希望我的默认行为与 SIG_DFL 相同,并忽略与 SIG_IGN 相同的行为,操作系统会这样做。

最佳答案

The GNU C Library Reference Manual有一整章解释有关信号处理的一切。

当您安装自己的处理程序时(请参阅signal()sigaction() 的联机帮助页),您总是会获得先前设置的信号处理程序(函数指针)。

previous_handler = signal(SIGINT, myhandler);

一般规则是,您始终可以重置为之前的处理程序并再次raise() 信号。

void myhandler(int sig) {
  /* own stuff .. */
  signal(sig, previous_handler);
  raise(sig);
  /* when it returns here .. set our signal handler again */
  signal(sig, myhandler);
}

通用规则有一个缺点:映射到信号的硬件异常通常分配给导致异常的特定指令。因此,当您再次发出信号时,关联的指令与原来的指令不同。这可以但不应该损害其他信号处理程序。

另一个缺点是,每个发出的信号都会导致大量处理时间。为防止过度使用 raise(),您可以使用以下替代方法:

  1. SIG_DFL 的情况下,函数指针指向地址 0(这显然不是有效地址)。因此,您必须重置处理程序并再次raise() 信号。

    if (previous_handler == SIG_DFL)
    {
      signal(sig, SIG_DFL);
      raise(sig);
      signal(sig, myhandler);
    } 
  2. SIG_IGN 的值为 1(也是无效地址)。在这里你可以返回(什么都不做)。

    else if (previous_handler == SIG_IGN)
    {
      return;
    } 
  3. 否则(既不是SIG_IGN 也不是SIG_DFL)您收到了一个有效的函数指针并且您可以直接调用处理程序,

    else
    {
      previous_handler(sig);
    }

当然,您还必须考虑不同的 API(请参阅 signal()sigaction() 的联机帮助页)。

关于c - 执行默认信号处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6015498/

相关文章:

c - c中没有返回错误

java - 如何在 Linux 上使用用户名和密码连接到我的 mysql 数据库

php - 如何通过终端获取 PHP 的 tar.gz 文件?

c - 如何使用信号在每个特定时间打印并产生键盘中断?

c - 当我只能定义一个可变长度数组时,为什么要使用 malloc()?

c - 将变量传递到另一个文件

linux - 使用 gnuplot 将命令放在多行中

c - 如何让 tcsetpgrp() 在 C 中工作?

c - 杀死使用clone()创建的子进程

c - 我正在寻找特定的搜索算法