获取std :: future的状态


82

是否可以检查astd::future是否完成?据我所知,唯一的方法是呼叫wait_for时长为零,并检查状态是否正确ready,但是还有更好的方法吗?


10
@CatPlusPlus除非我没有记错,否则valid仅检查将来是否具有共享状态(即返回,true直到get在将来被调用为止)。
David Brown

因此,如果get已被调用并返回存储的值,您是否还想要true?(我不确定为什么这样做会有用,因为您一次只能获得价值。)
James McNellis 2012年

@JamesMcNellis也许我误解或滥用了期货,但我想知道的是线程(或执行计算的任何对象)是否完成。QFuture::isFinished基本上相当于Qt 。
大卫·布朗

1
等待超时为零是许多平台上大多数API如何处理此类概念的方法……如此之多,以至于我将其视为实现该概念的“标准”方式。这让我对“更好的方法”的概念感到有些困惑……
asveikau 2012年

16
@asveikau我不知道这是标准做法。当我不想等待时,调用等待函数只是感觉很奇怪。
大卫·布朗

Answers:


84

你是正确的,除了打电话 wait_until给过去的时间(相当于过去),没有更好的方法。

如果想要更方便的语法,可以总是写一些包装器:

template<typename R>
  bool is_ready(std::future<R> const& f)
  { return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready; }

注意:如果推迟执行此功能,则永远不会返回true,因此,最好wait_for在经过一定时间或系统负载较低后,要同步运行推迟的任务,最好直接进行检查。


2
wait_for不会改变未来,因此可以将参数声明为const。
延斯·阿克布洛姆(JensÅkerblom)2014年

7
如果已经调用get或从未初始化过future,请考虑先检查valid()以避免运行时错误。
杰里米·索伦森

5
是否可以保证wait_for(chrono :: seconds(0))立即返回,或者在某些实现中会产生对线程的控制几毫秒?知道这很重要,因为编写游戏代码时要花费几毫秒的时间……
kynnysmatto 2015年

9
@kynnysmatto,在某些实现上,它获取一个互斥锁以安全地检查将来的状态,因此,如果该锁被争用(因为另一个线程正在使状态准备就绪,或者还检查就绪状态),则它将阻塞,而另一个线程可以运行,但是在良好的实现中,互斥量绝不能保持多于几条指令的时间,因此,即使是一毫秒也不要。GCC当前的实现完全不使用互斥锁,但是前一个使用了互斥锁,并且通过交换两个指针来使状态就绪,因此互斥锁仅在发生这种情况时非常短暂地锁定。
Jonathan Wakely

@Jonathan用g ++for(int i = 0; i < 1000; i++) f.wait_for(chrono::seconds(0));进行唤醒测试需要43毫秒的挂钟时间。
丹尼尔·金斯曼


9

我的第一选择将是调用wait_for了0期,并检查结果代码,可以是一个future_status::readyfuture_status::deferredfuture_status::timeout

cppreference中,他们声称valid() 检查结果是否可用,但是标准表示,如果引用共享状态,valid()则返回该状态,而与该状态是否就绪无关。true*this


7
cppreference现在已更新,并且指出“检查将来是否具有共享状态”。(不确定是要删除第二段还是对其进行编辑,因此我自己不会对其进行修改)。
默认值
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.