异常传播和 std::future
Posted
技术标签:
【中文标题】异常传播和 std::future【英文标题】:Exception propagation and std::future 【发布时间】:2013-01-08 19:49:38 【问题描述】:我的理解是,当异步操作抛出异常时,会被传播回调用std::future::get()
的线程。然而,当这样的线程调用std::future::wait()
时,异常不会立即传播——它会在随后调用std::future::get()
时被抛出。
但是,在这种情况下,如果未来对象在调用std::future::wait()
之后但在调用std::future::get()
之前超出范围,那么这种异常应该发生什么?
对于那些感兴趣的人,这里是一个简单的例子。在这种情况下,异常由 thread/future 包静默处理:
#include "stdafx.h"
#include <thread>
#include <future>
#include <iostream>
int32_t DoWork( int32_t i )
std::cout << "i == " << i << std::endl;
throw std::runtime_error( "DoWork test exception" );
return 0;
int _tmain(int argc, _TCHAR* argv[])
auto f = std::async( DoWork, 5 );
try
//f.get(); // 1 - Exception does propagate.
f.wait(); // 2 - Exception does NOT propagate.
catch( std::exception& e )
std::cout << e.what() << std::endl;
return -1;
return 0;
【问题讨论】:
我认为异常没有发生任何事情,它只是被忽略了。 (但我对此还不够熟悉,无法确定。) 我想重要的是要注意异常是由std::exception_ptr
s 跨线程传播的。所以对于系统来说,异常看起来会被捕获和处理,直到传播机制决定重新抛出它。
【参考方案1】:
它被忽略和丢弃,就像你 wait()
获取一个值但从不 get()
它一样。
wait()
只是说“阻塞,直到未来准备好”,即准备好值或异常。实际get()
值(或异常)取决于调用者。通常你只会使用get()
,无论如何它都会等待。
【讨论】:
啊!我会买这个,但它令人困惑 - 特别是如果 std::async 创建的 std::future 具有 void 结果类型。为这样的未来调用 get() 感觉很奇怪。 @Bukes:嘿,我能看到。但是不要把future<T>
想成“T
的结果”,把它想成“T
的计算结果”,当然可以例外。
@GManNickG 如果函数返回 void 那么你不认为调用 wait() 而不是 get() 有意义吗
@GManNickG 如果函数返回 void 那么你不认为调用 wait() 而不是 get() 有意义吗以上是关于异常传播和 std::future的主要内容,如果未能解决你的问题,请参考以下文章
kotlin协程硬核解读(5. Java异常本质&协程异常传播取消和异常处理机制)
kotlin协程硬核解读(5. Java异常本质&协程异常传播取消和异常处理机制)