Skip to content

Providing results – std::promise/future

Thread function stores result within a promise

A thread function can store its results and also exceptions within a std::promise:

#include<future>
// A promise holding a specific result type
typedef std::promise<SomeResult> MyPromise;
void DoProcessSomething(MyPromise& io_rPromise, int in_val)
{
    try
    {
        SomeResult result = CalculateResult(in_val);
        // Store result within promise
        io_rPromise.set_value(std::move(result));
    }
    catch (...)
    {
        // Store exception within promise
        io_rPromise.set_exception(std::current_exception());
    }
}

Remark: You can only store a value OR an exception.

Accessing results with use of a future

#include<future>
#include<thread>
typedef std::promise<SomeResult> MyPromise;
typedef std::future<SomeResult>  MyFuture;
{
    try
    {
        // Start thread and provide a promise
        MyPromise myPromise;
        std::thread t(DoSomething, std::ref(myPromise), 17);
        t.detach();
        // Get future to access results
        MyFuture myFuture (myPromise.get_future());
        ...
        // Finally wait until thread has provided result
        SomeResult result = myFuture.get();
        // Remark: an exception stored within the promise
        // may be rethrown here!
    }
    catch (std::exception const & e)
    {
        ...
    }
    catch (...)
    {
        ...
    }
}

Behind the scenes: the shared state

  • Internally a shared state is used to store a specific result or an exception. As soon as the result or the exception is stored within the shared state it becomes ready
  • When the shared state becomes ready the call to myFuture.get() will return
  • The thread function may continue working after it has provided the results within the shared state. To be sure that the thread really has terminated (and e.g. properly cleaned up all resources) before accessing the results you could use io_rPromise.set_value_at_thread_exit() and io_rPromise.set_exception_at_thread_exit() within the thread function.

Methods of std::future

MethodDescription
f.valid()returns true if the future has a valid state. Only in this case the following functions are available
f.get()returns the result/exception provided by the thread function; performs a blocking wait if the thread function has not yet finished; a deferred thread execution may be started here. The call will invalidate the state, i.e. f.get() can only be called once!
f.wait()performs a blocking wait if the thread function has not yet finished; a deferred thread execution may be started here.
f.wait_for(chrono::seconds(1.5))performs a blocking wait until the thread function has finished or the given timeout has elapsed; a deferred thread execution is NOT started.

For more info see std::future – complete reference at CppReference.com

Methods of std::promise

MethodDescription
p.get_future()returns a future object to be used for accessing the result stored within the promise
p.set_value(v)sets the given value as return value within the shared state and makes the state ready
p.set_value_at_thread_exit(v)sets the given value as return value within the shared state and makes the state ready at the end of the thread
p.set_exception(e)sets the given exception within the shared state and makes the state ready
p.set_exception_at_thread_exit(e)sets the given exception within the shared state and makes the state ready at the end of the thread

For more info see std::promise – complete reference at CppReference.com