有没有办法以保证无等待的方式检查 std::future 状态是否准备就绪?

Is there a way to check if std::future state is ready in a guaranteed wait-free manner?

我知道我可以通过以下方式检查 std::future 的状态:

my_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready

但根据 cppreference.com std::future::wait_for 在某些情况下可能会阻塞:

This function may block for longer than timeout_duration due to scheduling or resource contention delays.

timeout_duration为0时,是否仍然如此?如果是这样,是否有另一种方式以保证无等待的方式查询状态?

quote from cppreference is simply there to remind you that the OS scheduler is a factor here and that other tasks requiring platform resources could be using the CPU-time your thread needs in order to return from wait_for() -- regardless of the specified timeout duration being zero or not. That's all. You cannot technically be guaranteed to get more than that on a non-realtime platform. As such, the C++ Standard says nothing about this, but you can see other interesting stuff there -- see the paragraph for wait_for() under [futures.unique_future¶21]:

Effects: None if the shared state contains a deferred function ([futures.async]), otherwise blocks until the shared state is ready or until the relative timeout ([thread.req.timing]) specified by rel_­time has expired.

这里没有提到额外的延迟,但它确实说你阻止了,它仍然取决于实现是否wait_for()这里是yield()ing the thread1 first thing upon such blocking or immediately returning if the timeout duration is zero. In addition, it might also be necessary for an implementation to synchronize access to the future's status in a locking manner, which would have to be applied prior to checking if a potential immediate return is to take place. Hence, you don't even have the guarantee for lock-freedom,更不用说等待自由.

请注意,这同样适用于使用过去时间调用 wait_until

Is it still the case when timeout_duration is 0 ? If so, is there another way to query the state in a guaranteed wait-free manner ?

所以是的,尽管实施了 wait_free()情况仍然如此。因此,这是最接近 免等待 状态检查的方法。


1 简单来说,这意味着 "releasing" CPU 并将您的线程放在调度程序队列的后面,给其他线程一些 CPU-时间.

Is it still the case when timeout_duration is 0 ?

是的。 any 操作也是如此。 OS 调度程序可以暂停线程(或整个进程)以允许另一个线程在同一个 CPU.

上 运行

If so, is there another way to query the state in a guaranteed wait-free manner ?

没有。使用零超时是正确的方法。

甚至无法保证 std::future 的共享状态不会锁定互斥锁来检查它是否准备就绪,因此无法保证它是无等待的。

对于 GCC 的实现,就绪标志是原子的,因此不需要互斥锁,如果它就绪,则立即 wait_for returns。如果它还没有准备好,那么会有更多的原子操作,然后检查超时是否已经过去,然后是系统调用。因此,对于零超时,只有一些原子加载和函数调用(没有系统调用)。

回答你的第二个问题,除了等待,目前没有办法检查未来是否已经准备好。我们可能会在某个时候得到这个:https://en.cppreference.com/w/cpp/experimental/future/is_ready。如果您的运行时库支持并发扩展并且您不介意在代码中使用 experimental,那么您现在可以使用 is_ready()。话虽如此,我知道很少有必须检查未来状态的情况。你确定有必要吗?