何时使用std :: launch :: deferred?

Sau*_*ahu 13 c++ multithreading asynchronous c++11

来自Anthony William的书:

std::launch::deferred表示函数调用将被推迟到将来调用wait()get()调用.

X baz(X&);

auto f7 = std::async(std::launch::deferred, baz, std::ref(x)); //run in wait() or get()
//...
f7.wait();  //invoke deferred function
Run Code Online (Sandbox Code Playgroud)

与直接调用(baz(ref(x)))相比,此代码的好处或区别是什么?

换句话说,在这里拥有未来有什么意义?

Yak*_*ont 11

假设你有一个线程池.

线程池拥有一定数量的线程.说10.

添加任务时,它们会返回未来,并且它们会排入池中.

池中的线程唤醒,抓取任务,处理它.

当您在该池中有10个任务等待队列中的某个任务时会发生什么?好吧,陷入僵局.

现在,如果我们从此池中返回延迟的未来,该怎么办?

当你等待这个延期的未来它醒来时,检查任务是否完成.如果是这样,它就会完成并返回.

接下来,如果任务在队列中但尚未启动,它会从队列中窃取工作并在那里运行,然后返回.

最后,如果它是由队列运行但没有完成,它会做一些更复杂的事情.(通常最常用的最简单的版本是阻止任务,但这并不能解决某些病态情况).

在任何情况下,现在如果队列中的任务休眠等待队列中的另一个任务完成但尚未排队,我们仍然可以取得进展.


另一个用途是减少奥术.假设我们有一些懒惰的值.

我们不是计算它们,而是将共享期货与其中的计算步骤一起存储.现在任何需要它们的人都会做到.get().如果已经计算了该值,我们得到该值; 否则,我们计算它,然后得到它.

稍后,我们添加一个系统来做空闲或另一个线程的工作.在某些情况下,这些取代了延迟的懒惰期货,但在其他情况下却没有.


Ser*_*eyA 6

我认为,主要的好处是它可能在不同的线程中执行 - 实际上是未来的线程.这允许在线程之间传输"工作单元" - 即线程1创建未来,而线程2调用wait它.

  • @SauravSahu,不,我的意思是`wait`可以在一个与创建未来的线程不同的线程中调用. (3认同)
  • @SauravSahu我认为SergeyA试图做的区别是对于`std :: launch:async`,实现提供将执行工作的线程,而使用`std :: launch :: deferred`你提供线程(一个)读取值). (3认同)