std::atomic<int> g_atomic;
void thread0()
{
int oldVal = 0;
int newVal = 1;
while (g_atomic.compare_exchange_strong(oldVal, newVal, std::memory_order_acq_rel, std::memory_order_acquire))
{
// forever counting from 0 to 100 until unexpected value appears
oldVal = newVal;
newVal = (oldVal + 1) % 100;
};
}
void thread1()
{
// set unexpected value
g_atomic.store(-1, std::memory_order_release);
}
int main()
{
g_atomic.store(0);
std::thread t0(thread0);
std::thread t1(thread1);
t0.join();
t1.join();
return 0;
}
Can it happen that the write from thread1 is somehow overwritten in the loop of thread0 before it gets visible in thread0? The program would then run forever. This does not happen in my tests however im interested if there is any guarantee saying this will always be the case.
So, to provide a definitive answer to this, no, a write from thread1 will never be missed by thread0.
This is because std::atomic::compare_exchange_strong
is an atomic operation so the write from thread0 either happens before this operation starts (in which case it returns false
) or after it completes (in which case the call will fail next time round the loop).
If it was any other way, compare_exchange_strong
would have no utility, no?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With