A thread is created via a packaged task and a std::vector
is returned.
#include <iostream>
#include <future>
#include <thread>
#include <vector>
std::vector<int> func(int &arg)
{
std::vector<int> v = {1,2,3,4};
arg = 10;
return v;
}
int main()
{
std::packaged_task<std::vector<int>(int &)> pt{func};
auto fut = pt.get_future();
int arg = 0;
std::thread thr{std::move(pt), std::ref(arg)};
auto vec = fut.get();
std::cout << arg << std::endl; // data race here ?
thr.join();
}
The std::future
guarantees that the vector is synchronized with the main
thread (before join
),
but I am not sure about the status of the packaged task argument (which is passed by reference).
So the question is whether there is a data race on arg
?
int arg=0;
this happens-before we start the thread thr
, as it is sequenced-before it.
arg = 10;
this happens-before vec
is initialized, due to the .get()
call:
auto vec=fut.get();
which is sequenced-before
std::cout << arg << std::endl;
so I see no data race here.
While not authortative, cpp reference claims:
The promise is the "push" end of the promise-future communication channel: the operation that stores a value in the shared state synchronizes-with (as defined in std::memory_order) the successful return from any function that is waiting on the shared state (such as std::future::get).
there are similar words for std::async
as well. I believe a similar guarantee holds for packaged_task
; it is intended to be used as a primitive to help implement your own std::async
like behaviour after all.