当一个exception在multithreadingC ++ 11程序中未处理时会发生什么?

如果我有一个C ++ 11程序运行两个线程,其中一个抛出一个未处理的exception,会发生什么? 整个程序会不会是一场火热的死亡? 请问抛出exception的线程是否会死亡(如果是的话,我能否在这种情况下获得exception)? 还有其他的东西吗?

没有什么真的改变。 在n3290的措辞是:

如果找不到匹配的处理程序,则调用std::terminate()函数

terminate的行为可以用set_terminate来定制,但是:

所需的行为terminate_handler应该终止程序的执行而不返回给调用者。

所以程序在这种情况下退出,其他线程不能继续运行。

由于似乎有exception传播的合法兴趣,这至less有点相关的问题,这里是我的build议: std::thread将被视为一个不安全的原始,以build立如更高层次的抽象。 正如我们所表明的那样,如果在我们刚刚启动的线程中发生exception,那么所有的事情都会爆炸。 但是,如果在启动std::thread的线程中发生exception,我们可能会遇到麻烦,因为std::thread的析构函数要求*this要么被连接要么被分离(或者等价地, 不成为线程 ) 。 违反这些要求导致…调用std::terminate

std::thread危险的代码映射:

 auto run = [] { // if an exception escapes here std::terminate is called }; std::thread thread(run); // notice that we do not detach the thread // if an exception escapes here std::terminate is called thread.join(); // end of scope 

当然,有些人可能会争辩说,如果我们简单地detach每一个我们发起的线程,那么我们在第二点就是安全的。 问题是,在某些情况下, join是最明智的做法。 快速sorting的“天真”并行化需要等到子任务结束。 在这些情况下, join成为一个同步原语(rendez-vous)。

对我们来说幸运的是,我提到的那些更高层次的抽象确实存在,并且与标准库一起出现。 它们是std::asyncstd::future以及std::packaged_taskstd::promisestd::exception_ptr 。 上面的等效的exception安全版本:

 auto run = []() -> T // T may be void as above { // may throw return /* some T */; }; auto launched = std::async(run); // launched has type std::future<T> // may throw here; nothing bad happens // expression has type T and may throw // will throw whatever was originally thrown in run launched.get(); 

而事实上,不是调用async调用的线程,而是将降压传递给另一个线程:

 // only one call to get allowed per std::future<T> so // this replaces the previous call to get auto handle = [](std::future<T> future) { // get either the value returned by run // or the exception it threw future.get(); }; // std::future is move-only std::async(handle, std::move(launched)); // we didn't name and use the return of std::async // because we don't have to