必须用户提供的terminate()函数是否是线程安全的?

时间:2012-10-27 20:57:33

标签: 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设置的终止函数?

1 个答案:

答案 0 :(得分:7)

<强> Q1

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

<强> Q2

该标准表明,terminate_handler没有“在不返回调用者的情况下终止程序的执行”是未定义的行为。在我熟悉的实现中,如果terminate_handler尝试返回,无论是正常还是异常,都会调用abort()

<强> Q3

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

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

在C ++ 11中,这已经改变了,标准现在说使用的处理程序是调用terminate时的处理程序。这种改变是错误的,很可能在未来的草案中得到纠正。以下是跟踪此问题的LWG问题:

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

<强>更新

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

要使代码可移植,如果需要设置terminate_handler,请在程序启动期间,在抛出任何异常之前执行此操作,并且不要习惯在此之后调用set_terminate