Your scenario is too simple. On an architecture with strongly ordered memory semantics (e.g. x86 and descendants, which, given you refer to "my PC", is probably what you're using), with compiler optimizations turned off, as long as the compiler doesn't reorder threadProducer
's a = 1;
ahead of the function call (it has no reason to), doesn't cache the value of a
for the while (!a)
test, and doesn't eliminate the while(a){}
loop, the atomics won't make a difference.
Your existing code could fail without atomics:
- On a machine with weakly ordered memory semantics (the writes to
a
and val
could become visible in threadConsumer
in any order, and it could take an arbitrarily long for them to become visible). I suspect the locking built-in to the iostream
library, and the C stdio
it wraps, would probably trigger cache flushes though, so your I/O trying to observe the races is in fact changing the behavior.
- On any machine if the compiler chose to cache the value of
a
in threadConsumer
for efficiency (non-volatile
, non-atomic
values can be cached to save overhead because it's assumed they're only accessed from one thread, and the loading thread isn't changing it).
- On any machine if the compiler decides to eliminates the
while (a) {}
loop, due the non-atomic a
potentially creating an infinite loop if cached as suggested in #2.
- On any machine if the compiler chose to reorder
a = 1;
ahead of val = calculate_val();
(since neither line depends on any values computed in the other line, an optimizing compiler could choose to do them in either order). In practice, given the aforementioned locking in the I/O layers, the compiler won't swap these lines, but it could if the I/O were removed.
I'm not going to give an example of things that could go wrong, because a cursory search will find all sorts of examples of when and why you use atomics. What's important to know is that, even in your simple scenario where you thought it was safe without them, it wasn't. Even turning up optimizations might cause your code with a non-atomic a
to stop behaving on x86-64 machines, and x86-64 is already threading/atomics on easy mode.