I have a following program which uses std::atomic_thread_fences:
int data1 = 0;
std::atomic<int> data2 = 0;
std::atomic<int> state;
int main() {
state.store(0);
data1 = 0;
data2 = 0;
std::thread t1([&]{
data1 = 1;
state.store(1, std::memory_order_release);
});
std::thread t2([&]{
auto s = state.load(std::memory_order_relaxed);
if (s != 1) return;
std::atomic_thread_fence(std::memory_order_acquire);
data2.store(data1, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);
state.store(2, std::memory_order_relaxed);
});
std::thread t3([&]{
auto d = data2.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
if (state.load(std::memory_order_relaxed) == 0) {
std::cout << d;
}
});
t1.join();
t2.join();
t3.join();
}
It consists of 3 threads and one global atomic variable state used for synchronization. First thread writes some data to a global, non-atomic variable data1 and sets state to 1. Second thread reads state and if it's equal to 1 it modifies assigns data1 to another global non-atomic variable data2. After that, it stores 2 into state. This thread reads the content of data2 and then checks state.
Q: Will the third thread always print 0? Or is it possible for the third thread to see update to data2 before update to state? If so, is the only solution to guarantee that to use seq_cst memory order?