Consider the following program:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{[] {
b.arrive_and_wait();
std::cout << i << '\n';
}};
std::thread t1{[] {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
Is this program guaranteed to print out 2
, even though i
is not an atomic variable?
According to cppreference:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
This suggests that there is a synchronization point on each arrive_and_wait
call. However I am not sure if the compiler is allowed to reorder the read/write operations on i
, since it is non-atomic.
arrive_and_wait()
synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2
) inter-thead happen before statements that are sequenced after B (cout << i
). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads. – Mazza