c++ - 用户提供的 terminate() 函数必须是线程安全的吗?

标签 c++ multithreading c++11 terminate-handler

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 结束,那么程序就会结束,但是如果用户提供的终止没有中止程序会发生什么?

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

最佳答案

第一季度

是的,std::terminate 可以并发调用。

第二季度

标准规定 terminate_handler 不“终止程序执行而不返回调用者”是未定义的行为。在我熟悉的实现中,如果 terminate_handler 尝试返回,无论是正常还是异常,都将调用 abort()

第三季度

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

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

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

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

更新

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

为了使您的代码可移植,如果您需要设置一个terminate_handler,请在程序启动时设置,以免抛出任何异常,并且不要养成调用set_terminate<的习惯 之后。

关于c++ - 用户提供的 terminate() 函数必须是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13104124/

相关文章:

c++ - C++11 中的默认构造函数、POD 的初始化和隐式类型转换

c++ - 对象 union 与指针 union

C++ STL 映射 - 条件插入

c++ - 写入串口 (C++/Windows)

c++ - 为什么 cout 不显示 x?

java - 并发访问实用程序静态方法

c++ - 如何在 3D 点上绘制文本?

c++ - 在 C/C++ 共享内存中等待和通知

java - 如何停止计时器

c++ - 如果不直接使用,模板参数会丢失左值引用