I have a question about page 270 of Effective Modern C++, written by the Scott Meyers.
Line 5/6, He writes: "The only subtlety is that each reacting thread needs ITS OWN COPY of the std::shared_future that refers to the shared state, ..."
My question is: Why are we obliged to pass a copy of the std::shared_future
to each lambda function in each thread? Whereas à priori, I don't see any problem to pass it by reference, such that there is a unique shared state that would be used by different thread?
I wrote a code adapted from the book of Dr Scott Meyers which works, even if I pass sf par reference.
Thus, is it possible to pass it by reference?
#include <future>
#include <vector>
std::promise<void> p;
void react(){}
void detect()
{
auto sf = p.get_future().share();
std::vector<std::thread> vt;
int n=10;
for(int i=0;i < n; i++)
{
vt.emplace_back([sf]{sf.wait();
react();
});
}
p.set_value();
for(auto& t : vt)
t.join();
}
int main()
{
detect();
return 0;
}
If you pass by reference, multiple threads are accessing the same instance of shared_future
. This potentially results in a data race and is undefined behavior. If multiple threads access the shared state via their own copy of shared_future
, the library makes sure that they are synchronized.
The cppreference page on get
says:
It effectively calls
wait()
in order to wait for the result.
And the cppreference page on wait
says:
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 astd::shared_future
.