【问题标题】:C++ exceptions and signal handlersC++ 异常和信号处理程序
【发布时间】:2011-09-25 23:43:44
【问题描述】:

我正在阅读 Bjarne Stroustrup 的C++ 的设计和演变。关于异常处理和异步信号如下:

异常可以用来处理信号之类的事情吗?几乎可以肯定,在大多数 C 环境中都不会。问题是 C 使用了像 malloc 这样不可重入的函数。如果 malloc 中间发生中断并导致异常,则无法阻止异常处理程序再次执行 malloc。

调用序列和整个运行时库都是围绕重入要求设计的 C++ 实现,这将使信号有可能抛出异常

作者所说的“没有办法阻止异常处理程序再次执行malloc”是什么意思?使函数可重入如何使信号处理程序抛出异常成为可能?

【问题讨论】:

    标签: c++ exception language-design signal-handling


    【解决方案1】:

    例如,如果对 malloc 的调用引发了一个信号,那么如果您从该信号处理程序中抛出异常,则异常抛出逻辑可以再次调用 malloc。由于 malloc 不可重入,您最终会遇到未定义的行为。

    处理信号的一种方法是将信号事件推入事件队列并立即从信号处理程序返回。然后,当事件循环处理信号事件时,它可以为所欲为,因为它不在信号处理程序的受限上下文中。

    【讨论】:

      【解决方案2】:

      如果函数可以在执行过程中被中断并在中断的调用完成之前再次调用,则该函数是“可重入的”。另一种看待它的方式:可以从信号处理程序中调用可重入函数。从信号处理程序中调用不可重入函数的所有赌注都没有了。应该从信号处理程序内部调用的唯一函数是那些已知可重入的函数。

      malloc 不可重入。如果 malloc 发生 kaboom,则无法判断它是否在更新 malloc 在幕后使用的任何全局数据以跟踪分配的数据时发生了 kaboom。

      信号处理程序与异常的另一个问题:在信号处理程序中执行的代码本质上是在与主代码不同的线程中运行的。 如果可以处理信号,则信号处理程序的返回将返回到发出信号的点之后。您将如何在信号处理程序中引发异常?这样做,信号处理程序不再返回!这意味着其余的执行是在信号处理程序中有效地完成的。现在当另一个信号出现时会发生什么?这两个概念只是不混合。重入只是这里的冰山一角。

      【讨论】:

        【解决方案3】:

        在我看来,这部分对于当前的 C++ 并没有多大意义。

        在 C++ 中,无法将异常用作信号,因为信号意味着要执行处理程序,然后(可能)继续执行。

        但是,C++ 异常不能以这种方式工作。一旦您到达异常处理程序,堆栈已经回滚,并且在处理后无法“继续”:在 throw 之后(或在发生异常的函数调用之后)无法到达语句抛出)。

        信号是异步的,但不会中断,并且在信号可能后继续(即使当然必须注意信号处理程序中所做的事情),异常反而会中断程序流并且不可能继续。

        我想说这两个想法在逻辑层面上是不兼容的,图书馆是否可重入并不重要。

        可能在早期的 C++ 设计中,有一个异常恢复选项...

        【讨论】:

        • 很高兴您指出未捕获抛出的异常后无法继续执行程序。
        猜你喜欢
        • 2017-05-06
        • 1970-01-01
        • 1970-01-01
        • 2021-06-29
        • 2020-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多