11

http://en.cppreference.com/w/cpp/error/terminate中所述,调用终止的原因有很多。我可以想象其中一些原因几乎同时发生在两个线程中的情况。

Q1设置的终止函数std::set_terminate是否可以同时调用两次或多次,同时我的意思是第二次调用在第一次结束之前开始。

  Thread1   Thread2
    |          |
    _          |
    t          |
    e          |
    r          |
    m          |
    i          _
    n          t
    a          e
    t          r
    e          m
    -          ?

Q2如果 Q1==YES,那么如果第一次终止结束会发生什么。我猜如果它以 std::abort 结束,那么程序结束,但是如果用户提供的 terminate 没有中止程序会发生什么?

Q3调用的终止函数是std::set_terminate在导致终止调用的线程的上下文中设置的吗?

4

1 回答 1

7

第一季度

是的,std::terminate可以同时调用。

第二季度

terminate_handler该标准表示,不“在不返回调用者的情况下终止程序的执行”是未定义的行为。在我熟悉的实现中,是否会调用terminate_handler正常或异常返回的尝试。abort()

第三季度

设置的函数std::terminate是全局的,而不是线程本地的。所以一个线程可以影响另一个线程。

在 C++98/03 中,由于未捕获的异常而调用terminate_handler使用的 whenterminate是抛出异常时生效的那个,而不是terminate实际调用时生效的那个(尽管它们通常是相同的)。

在 C++11 中,这种情况发生了变化,现在标准规定使用的处理程序是调用时已到位的处理程序terminate。此更改是错误完成的,很可能会在未来的草稿中更正。这是跟踪此问题的 LWG 问题:

http://cplusplus.github.com/LWG/lwg-active.html#2111

更新

在堪萨斯州 Lenexa 举行的 2015 年春季会议上,LWG 决定标准化现有行为,并在堆栈展开期间调用新行为时未指定何时terminate_handler生效。set_terminate即允许实现遵循 C++98/03 规则或 C++11 规则。

为了让你的代码具有可移植性,如果你需要设置 a terminate_handler,请在程序启动时进行,在任何异常抛出之前进行,并且不要养成之后调用的习惯set_terminate

于 2012-10-27T21:56:29.923 回答