Reputation: 8617
Cppreference says about std::future
that
The creator of the asynchronous operation can then use a variety of methods to query, wait for, or extract a value from the std::future.
Who is the creator of the asynchronous operation? Is it the thread that creates the std::future
object, or any thread that has access to that object? In the end, my question is if non-creators can also use the get
method on the std::future
.
In particular, I would like to know if this piece of code is correct:
std::future<int> foo;
std::thread t([&foo](){
foo = std::async(std::launch::async, [](){ return 4; });
});
t.join();
int n = foo.get(); // can the main thread call foo.get()?
Upvotes: 3
Views: 156
Reputation: 21576
Who is the creator of the asynchronous operation? Is it the thread that creates the std::future object, or any thread that has access to that object?
There are essentially 3 things that can create such "asynchronous operation":
std::async
std::promise
std::packaged_task
These "creators" create a so called shared state, in which the std::future
obtained equally shares access to. The shared state is where the results of such operation is stored. both the provider (an std::async
, std::promise
, or std::packaged_task
object) and the consumer (the std::future
obtained) accesses the shared state in a thread safe manner, its an implementation detail you shouldn't be bothered about.
In the end, my question is if non-creators can also use the get method on the
std::future
.
Of cause; An "asynchronous operation" typically takes place in a different thread of execution, and the purpose of std::future
is to safely query and access the results of such "asynchronous operation" happening somewhere else, without you explicitly using any extra synchronization mechanism.
In particular, I would like to know if this piece of code is correct:
std::future<int> foo; std::thread t([&foo](){ foo = std::async(std::launch::async, [](){ return 4; }); }); t.join(); int n = foo.get(); // can the main thread call foo.get()?
While this "particular short snippet" doesn't seem to invoke a race condition; It's not in any way a good code. At any point in time, the std::future
to a shared state obtained from an "asynchronous operation" should not be used by multiple thread at a time.
In your case, the get()
and the assignment operator
isn't thread-safe. And sooner or later, this code will quickly grow to invoke a race-condition
One more note, the use of a std::thread
in your code isn't needed, in practice a decent implementation will create a new thread or use a thread pool when your launch policy is std::launch::async
. Hence you should just do:
std::future<int> foo = std::async(std::launch::async, [](){ return 4; });
int n = foo.get();
Upvotes: 1