R. *_*des 59 c++ multithreading exception c++-faq c++11
如果我有一个C++ 11程序运行两个线程,其中一个抛出一个未处理的异常,会发生什么?整个程序会死于火热的死亡吗?抛出异常的线程是否会单独死亡(如果是这样,我可以在这种情况下获得异常)吗?还有别的吗?
Ben*_*igt 50
什么都没有改变.n3290中的措辞是:
如果未找到匹配的处理程序,
std::terminate()则调用该函数
行为terminate可以自定义set_terminate,但是:
必需的行为:A
terminate_handler应终止程序的执行而不返回调用者.
所以程序在这种情况下退出,其他线程无法继续运行.
Luc*_*ton 28
由于似乎对异常传播有合理的兴趣,这与问题略有关联,这里是我的建议: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
Run Code Online (Sandbox Code Playgroud)
当然,有些人可能会争辩说,如果我们简单地detach编辑我们发布的每一个帖子,那么我们在第二点就是安全的.问题在于,在某些情况下,这join是最明智的做法.例如,快速排序的"天真"并行化需要等到子任务结束.在那些情况下join充当同步原语(rendez-vous).
对我们来说幸运的是,我提到的那些更高级别的抽象确实存在并且随标准库一起提供.他们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();
Run Code Online (Sandbox Code Playgroud)
事实上,而不是调用调用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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13210 次 |
| 最近记录: |