信号处理 [英] signal handling

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

问题描述

我只是用在Mac OS X信号播放。

I'm just playing with signal in Mac OS X.

为什么以下code不会产生我的信号处理后的SIGSEGV默认行为已经完成?
在Linux下,code正常工作。

Why does the following code not produce the default behavior of SIGSEGV after my signal handler has finished? Under Linux, the code works fine.

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

void err_crash();

void my_signal_handler (int signal)
{
    fprintf(stderr, "signal == %i\n", signal);
    fflush(stderr);
    err_crash();
}

void err_crash()
{
    static int count= 0;
    if (count)
        signal(SIGSEGV, SIG_DFL);       /* break recursion loop if we recursed */
    count++;

    // one of the two should really crash ;)
    ((void)(*((int volatile *)NULL)));
    *((int *)NULL) = 42;

    abort();                            /* in case we're not crashed yet... */
}

int main ()
{
    signal(SIGSEGV, my_signal_handler);
    err_crash();
    return 0;
}

编辑:
我得到的输出如下:

The output I get is the following:

bonecrusher:devel sw$ g++ signal_problems.cpp -o foo
bonecrusher:devel sw$ ./foo 
signal == 11
^C
bonecrusher:devel sw$

问题是,我想,该方案的信号== 11 ,但它永远落选后输出终止,我要打断它。

The problem is that I want that the program terminates after the output of signal == 11, but it rans forever and I have to interrupt it.

推荐答案

这实际上造成了我的大脑冻结了几分钟,为什么人们不应该使用信号()的原因在这个时代,只有在我成长壮大。

This actually caused me brain freeze for a few minutes, and the reason why one should never use signal() in this day and age only grew stronger in me.

首先,从该名男子页信号()

信号()的行为在整个变化
  UNIX版本,并且也各不相同
  历史在不同版本
  Linux的。避免使用它:使用
  的sigaction(2)来代替。

The behavior of signal() varies across UNIX versions, and has also varied historically across different versions of Linux. Avoid its use: use sigaction(2) instead.

和进一步下跌:


      
  • 如果处置被设定为一个函数,那么第一任
      配置被重置为SIG_DFL,或
      信号被阻断(见可移植性
      下文),然后调用处理程序
      有说法正负号。如果调用
      该处理程序引起的信号要
      受阻,那么信号畅通
      在从处理程序返回。

  •   

在原来的Unix系统中,安装处理程序时,配置被重置为SIG_DFL,做过的,然后在相同类型的块输入信号,它跑了处理函数。系统V提供了这一点,和Linux内核做了同样的。

In the original Unix systems, when a handler was installed, the disposition was reset to SIG_DFL, did not block incoming signals of the same type, and then it ran the handler function. System V provided this, and the linux kernel does the same.

这意味着,一旦code是一个Linux系统上运行,一旦第二个异常被调用时,它会直接退出。

This means that, once the code is run on a linux system, once second exception is called, it will exit directly.

现在到了有趣的部分。 BSD试图改善这种行为。从手册页又说:

Now to the fun part. BSD tried to improve this behaviour. From the man pages again:

在BSD,当信号处理程序
  调用时,信号处置不
  复位,并进一步实例
  信号从被阻塞
  交付而处理程序
  执行

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.

此外,由于Mac OSX上部分是基于BSD,一旦code是一个Mac OSX上运行,一旦第二个异常被调用时,这将是并等待的处理程序第一种例外退出。但是,因为你永远不会退出,你有一个僵局。

And since mac osx is partly based on BSD, once the code is run on a mac osx, once second exception is called, it will be pending and wait for the handler of the first exception to exit. But since you will never exit, you have a deadlock.

这就是为什么应该使用的sigaction(),而不是从不信号()

Thats why one should use sigaction() instead and never signal().

我们一些提示:

处理程序要短,并快速返回。如果您正在执行的计算和调用其他功能你可能做错了什么。信号不是一个事件驱动架构的替代品。

Handlers should be short, and return quickly. If you are performing calculations and calling other functions you are probably doing something wrong. Signals are not a substitute for an event driven framework.

调用不属于异步安全是坏的功能。试想,如果fprintf中到在通话过程中的异常发生的事情会发生什么,以及处理程序 fprintf中内被再次调用。因为它们在流本身操作两个信号处理程序和程序的数据可能会损坏。

Calling functions that are not async-safe is bad. Consider what would happen if an exception happened during a call to fprintf, and inside the handler fprintf was called again. Both the signal handlers and the programs data could be corrupted since they operate on the stream itself.

一些更多的阅读:做与不要信号处理程序

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

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