我知道我可以通过以下方式检查std::future
的状态:
my_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready
但是根据cppreference.com,std::future::wait_for
在某些情况下可能会阻止:
由于调度或资源争用延迟,此功能可能阻塞的时间超过timeout_duration。
timeout_duration
为0时是否仍然如此?如果是这样,还有另一种方法可以保证无等待地查询状态吗?
答案 0 :(得分:4)
quote from cppreference只是在这里提醒您,操作系统调度程序是其中的一个因素,需要平台资源的其他任务可能正在使用线程所需的CPU时间才能从wait_for()
返回-无论指定的超时持续时间是否为零。就这样。从技术上讲,您不能保证在非实时平台上能获得更多收益。因此,C ++标准对此一无所获,但您可以在此处看到其他有趣的内容-请参见[futures.unique_future¶21]下wait_for()
的段落:
效果:如果共享状态包含延迟功能,则无 ([futures.async]),否则阻止,直到共享状态就绪或 直到由指定的相对超时([thread.req.timing])
rel_time
已过期。
这里没有这样提及额外的延迟,但是它确实表明您 被阻止,并且无论wait_for()
是否为{{3 }}在此类阻塞时首先对线程 1 进行操作,或者如果超时时间为零,则立即返回。另外,对于实现而言,也可能有必要以锁定方式同步对未来状态的访问,这必须在检查是否要立即发生潜在回报之前应用。因此,您甚至没有yield()
的保证,更不用说等待自由了。
请注意,过去一段时间致电lock-freedom也是如此。
timeout_duration为0时是否仍然如此?如果是这样,那里 保证无等待状态查询状态的另一种方法?
是的,尽管实施了wait_free()
,但情况仍然如此。。因此,这是最接近您等待状态检查的 free-。
1 简而言之,这意味着“释放” CPU,并将您的线程放在调度程序队列的后面,从而给其他线程一些CPU时间。
答案 1 :(得分:1)
timeout_duration为0时是否仍然如此?
是的。 任何操作都是如此。操作系统调度程序可以暂停线程(或整个进程),以允许另一个线程在同一CPU上运行。
如果是,是否还有另一种以保证免等待的方式查询状态的方法?
不。使用零超时是正确的方法。
甚至无法保证std::future
的共享状态不会锁定互斥体以检查其是否准备就绪,因此不可能保证它没有等待。
对于GCC的实现,ready标志是原子的,因此不需要互斥锁,如果就绪,则wait_for
立即返回。如果还没有准备好,那么还有一些原子操作,然后检查超时是否已经过去,然后进行系统调用。因此,对于零超时,仅存在一些原子负载和函数调用(无系统调用)。
答案 2 :(得分:1)
要回答第二个问题,除了等待,目前无法检查未来是否已经准备就绪。我们可能会在某个时候得到这个:https://en.cppreference.com/w/cpp/experimental/future/is_ready。如果您的运行时库支持并发扩展,并且您不介意在代码中使用experimental
,那么现在就可以使用is_ready()
。话虽如此,我知道在少数情况下您必须检查未来的状态。您确定有必要吗?