在多线程c++ 11程序中,当异常未处理时会发生什么
What happens when an exception goes unhandled in a multithreaded C++11 program?
如果我有一个运行两个线程的c++ 11程序,其中一个抛出了一个未处理的异常,会发生什么?整个项目会不会死得很惨?抛出异常的线程会单独死亡吗(如果是的话,我可以在这种情况下获得异常吗)?完全不同的东西?
一切都没有改变。n3290中的措辞是:
如果没有找到匹配的处理程序,则调用函数
std::terminate()
terminate
的行为可以用set_terminate
来定制,但是:
所需行为:
terminate_handler
应终止程序的执行而不返回调用者。
在这种情况下程序退出,其他线程不能继续运行
由于似乎对异常传播有合法的兴趣,并且这与问题稍微相关,因此我的建议是:将std::thread
视为构建例如更高级别抽象的不安全原语。它们在异常方面具有双重风险:如果在我们刚刚启动的线程中出现异常,那么一切都会爆炸,正如我们所展示的那样。但是,如果在启动std::thread
的线程中出现异常,我们可能会遇到麻烦,因为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
是最明智的做法。例如,快速排序的"幼稚"并行化需要等到子任务结束。在这些情况下,join
充当同步原语(一个会合点)。
幸运的是,我提到的那些更高层次的抽象确实存在,并且随标准库而来。它们是std::async
, std::future
以及std::packaged_task
, std::promise
和std::exception_ptr
。上面的等价的异常安全版本:
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
的线程中不调用get
可以将buck传递给另一个线程:
// 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
相关文章:
- 在c++中实现LinkedList时,应出现未处理的错误
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 在C++程序中使用的迭代器中未处理的异常
- 在 ******.exe 中0x00000000772CA267 (ntdll.dll) 处未处理的异常:0xC0000
- 未处理的异常与 cudaMemcpy2D
- 处理未处理的异常更改C++
- for 循环中未处理的异常
- VisualC++ 2010 有没有办法找出有关未处理异常错误的更多详细信息
- 为什么此代码导致未处理的异常失败
- 瓦尔格林德:注意到但未处理的国际奥克特尔;是否有必要处理以及如何找到?
- 在OpenCV_core310.dll中使用findContours函数时,OpenCV引发未处理的异常
- 来自API的错误代码..处理什么是好的做法
- 0x0F50DF58:0xC0000005:访问冲突读取位置0x0047CA04时未处理的异常
- 使用 getline 时未处理的异常
- 错误 : 异常 : 引发未处理的异常: 读取访问冲突.0xDDDDDDDD临时温度
- 核心消息传递中未处理的异常.dll在程序关闭期间
- 在多线程c++ 11程序中,当异常未处理时会发生什么
- 什么是类型为"System.Runtime.InteropServices.SEHException"的未处理异常
- 此异常是什么意思>第一次机会异常在 Project3 中0x000007FEFD38A06D时未处理的异常.exe