120

Is it possible to check if a std::future has finished or not? As far as I can tell the only way to do it would be to call wait_for with a zero duration and check if the status is ready or not, but is there a better way?

7
  • 11
    @CatPlusPlus Unless I'm mistaken, valid only checks if the future has a shared state (i.e. It returns true until get is called on the future). Commented Jun 5, 2012 at 1:11
  • So, if get has been called and returns the stored value, do you still want true? (I'm not sure why this would be useful, since you can only get the value once.) Commented Jun 5, 2012 at 1:28
  • @JamesMcNellis perhaps I am misunderstanding or misusing futures, but what I want is to know if the thread (or whatever is performing the calculation) is finished or not. The equivalent of Qt's QFuture::isFinished basically. Commented Jun 5, 2012 at 3:06
  • 2
    A wait with a zero timeout is how most APIs across many platforms deal with such a concept... So much so that I would consider it the "standard" way of approaching the concept. This makes me a bit puzzled at the notion of "a better way"... Commented Jun 13, 2012 at 17:53
  • 25
    @asveikau I was not aware this was a standard practice. It just feels odd to call a wait function when I do not wish to wait. Commented Jun 13, 2012 at 18:55

4 Answers 4

114

You are correct, and apart from calling wait_until with a time in the past (which is equivalent) there is no better way.

You could always write a little wrapper if you want a more convenient syntax:

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

N.B. if the function is deferred this will never return true, so it's probably better to check wait_for directly in the case where you might want to run the deferred task synchronously after a certain time has passed or when system load is low.

Sign up to request clarification or add additional context in comments.

8 Comments

wait_for doesn't mutate the future so the parameter could be declared as const.
Consider checking valid() first to avoid run time errors if get was already called or the future was never initialized.
Is wait_for(chrono::seconds(0)) guaranteed to return immediately or could it yield the control of the thread for a couple of milliseconds on some implementations? This would be quite important to know as a couple of milliseconds is a lot of time when coding a game...
@kynnysmatto, on some implementations it acquires a mutex lock to safely inspect the state of the future, so if that lock is contended (because another thread is making the state ready, or also checking for readiness) then it will block, and another thread could run, but on a good implementation the mutex should never be held for more than a few instructions, so not even a single millisecond. GCC's current implementation doesn't use a mutex at all, but the previous one did and making the state ready is done by swapping two pointers, so the mutex is only locked very briefly while that happens.
A large part of that time is getting the current time. If you use wait_until(chrono::system_clock::time_point::min()) you don't need the current time, and it's faster. That optimisation is specific to GCC though, and for GCC 11 you'd need to use steady_clock instead of system_clock as we're about to change the clock that is used under the covers.
|
22

There was an is_ready member function in the works for std::future but the proposal was abandoned.

Currently, the VC implementation has an _Is_ready() member.

2 Comments

Note that the _Is_ready() member function is NOT thread-safe. It accesses the _Ready flag of the associated state in an unguarded way. This is at least the case for VS2019 16.2.
lol, typical C++. Something is "in the works" in 2014 and in 2023 it's nowhere to be found.
14

My first bet would be to call wait_for with a 0 duration, and check the result code that can be one of future_status::ready, future_status::deferred or future_status::timeout.

valid() will return true if *this refers to a shared state, independently of whether that state is ready or not. See cppreference.

1 Comment

cppreference has now been updated and states "checks if the future has a shared state". (Not sure if you want to remove your second paragraph or edit it, so I'll won't modify it myself).
-2

Since C++11, std::future now has both a wait() and a get() method, which will wait until the future has a valid response, with the latter method waiting (blocking) and then returning a result when it is ready.

If you want to check if it's ready without blocking, then I've done the same as what David Rodríguez - dribeas suggested; call wait_for with a 0 (or maybe up to 10ms) duration, and check the result code that can be one of future_status::ready, future_status::deferred or future_status::timeout. How short the delay needs to be depends on your needs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.