如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
设置的终止函数?
答案 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
。