My question is about thread synchronization. Please see the code below:
std::vector<int> v_int;
for (size_t i = 0; i < 5; ++i) {
v_int.emplace_back(i);
}
auto f_async = std::async(std::launch::async,
[](auto v_int) mutable {
for (auto& el : v_int.get()) {
el += 10;
}
}, std::ref(v_int));
//more instructions...
f_async.get();
My question is how the new thread spawned by std::async "sees" the modifications done by the (main) thread to the vector, given that there is no acquire-release (mutex, atomic bool, atomic flag...) to protect the vector?
Is there an implicit sequential consistency given that the new thread "happens" after the complete write to the vector?
A typical producer/ consumer would look like this:
std::vector<int> v_int_global;
std::atomic<bool> data_ready{ false };
void producer_int() {
for (size_t i = 0; i < 5; ++i) {
v_int_global.emplace_back(i);
}
data_ready.store(true, std::memory_order_release);
}
void transformer_int() {
while (!data_ready.load(std::memory_order_acquire));
for (auto& el : v_int_global) {
el += 10;
}
}
int main() {
std::thread t1 (producer_int);
std::thread t2 (transformer_int);
t1.join();
t2.join();
}
Thank you.
.get
on the returned future, which effectively makes this whole example synchronous. If you were to move the code that populatesv_int
to be between the call tostd::async
and the call tof_async.get
, you would have UB. – 0x5453