cppreference is explicit about calling std::shared_future<T>::wait from multiple threads:
Calling wait on the same std::shared_future from multiple threads is not safe; the intended use is for each thread that waits on the same shared state to have a copy of a std::shared_future.
But I can't find a basis for this assertion. There is nothing in the standard marking wait as some kind of special case. While the standard says that the methods on a single shared_future instance are not synchronized, you don't need synchronization as long only const methods are being called:
[17.6.5.9/3] A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const arguments, including this.
There are contradicting answers to be found on SO. Does anyone have an authoritative source on this which explains how calling a const method on a from stdlib could lead to a race condition?
The C++11 standard contained a caveat on the shared state of futures and shared_futures:
[futures.state/10] Accesses to the same shared state conflict (1.10)
Explicit exceptions to the usual rule of const library functions being thread-safe are allowed, as section 17.6.5.9 begins:
[res.on.data.race/1] ... Every standard library function shall meet each requirement unless otherwise specified. ... (emphasis mine)
However, C++14 changed the rule about shared state to:
[futures.state/11] Access to the result of the same shared state may conflict (1.10). [ Note: this explicitly specifies that the result of the shared state is visible in the objects that reference this state in the sense of data race avoid- ance (17.6.5.9). For example, concurrent accesses through references returned by shared_future::get() (30.6.7) must either use read-only operations or provide additional synchronization. — end note ]
I suspect the warning on cppreference.com was added under C++11, and never updated to reflect the wording in the later standards.
Since neither shared_future::wait() nor future::wait() refer to the shared state's result, both should now be data-race free.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With