future和 promise的关键点是它们允许在两个任务间传输值,而无须显式使用锁”系统”高效地实现了这种传输。基本思路很简单:当一个任务需要向另一个任务传输某个值时,它把值放人 promise中。具体的C++实现以自己的方式令这个值出现在对应的future中,然后就可以从其中读取这个值了(通常是任务的启动者读取此值)。这种模式如下图所示:
如果我们有一个名为fx的future<X>,则可以使用get()得到一个类型为X的值:
X v=fx.get(); //if necessary,wait for the value to get computed
如果值还未准备好,线程会阻塞直至值准备好。如果值无法正确地计算出来,则get()会抛出一个异常(可能是系统抛出的,也可能是从使用get()得到数据的任务传递来的)
promise的主要目的是提供与 future的get()相匹配的简单的“放置”操作(名为set_vaue(和 set_exception()。“期货”( future)和“承诺”( promise)的命名是历史遗留问题,所以请不要批判或赞美我。现实中像这样的双关语有很多。
如果你有一个 promise,并且需要把类型为Ⅹ的结果发送给 future,那么你要么传递个值,要么传递一个异常。例如:
void f(promise<X>& px) //一个任务:将结果放在px中{//...try{X res;//计算一个值,保存在res中..px.set_value(res);}catch(...) //糟糕:不能正确计算res{//将异常传递给future的线程px.set_exception(current_exception());}}
current_exception(表示捕获的异常(见30.4.1.2节)。
为了处理经过 future传递的异常,get()的调用者必须准备好在某处捕获它。例如
void g(future<X>& fx) //一个任务:从fx获取结果{//...try{X v=fx.get(); //如必要,等待值准备好//使用v}catch(...) //糟糕:v不能正确计算{//处理错误}}
