很多时候,异步处理一件事,会不止一个线程都需要关心这件事情的结果。这个需求如果仅仅通过future<T>对象的wait_for()或wait_until()接口等待结果,并不能满足。
因为这二者都只负责等结果,不负责取结果,更不负责“催”结果。遇上有拖延症的异步过程还没有启动,这二者都不负责“催促”启动。
因此,最终需要调用future<T>对象的get()或wait()。
既然不止一个线程需要关注操作结果,就自然有多个线程会去调用同一个future<T>的get()或wait()接口,这样可能造成目标操作被执行多次,过程示意如图12-2所示:
线程1判断目标过程未启动之后,刚刚要启动目标过程,线程2要来了,它也发现目标过程还没启动,于是也会进入if内部语句……
一句话,future<T>的设计意图:根本不希望被重复使用。包括多个线程重复使用同一个future<T>对象,也包括同一个线程重复调用一个future<T>对象的get()操作。
该意图有两点体现:一是future<T>拷贝构造、复制操作都标示deleted;
二是C++标准规定,调用同一个future<T>的get()操作多次,结果将“不可预期”,当前GCC的实现是在第二次调用时抛出std::future_error异常。请实测以上两点。
future<T>拷贝构造、复制操作都标示deleted
如果确定要在多个线程上处理同一异步操作的结果,需要使用shared_future
【小提示】:如何理解shared_future
我们一直讲future解释成“存根/收条”,以便强调通过它可以查询可以查询异步处理状态,获取异常处理结果。
普通future就是一个收条只能用一次(钱还了,借条也请作废),而 shared_future则是一个收条可以用多次。