Since you didn't declare flag
as std::atomic<bool>
, the compiler is allowed to assume that the variable won't be changed by another thread, unless these accesses are separated by synchronization points.
For this reason, it is likely that the compiler decided to optimize the while
loop of the function method
in the following way: Instead of reading flag
from memory in every loop iteration, it will only read it once from memory and will cache it in a CPU register, so that it only has to check the value in the CPU register in every loop iteration (which is faster than reading from memory). Therefore, this thread may not notice when flag
is changed by another thread, because its cached copy will remain unchanged.
Or possibly, the compiler was smart enough to notice that flag
will never change in the while
loop. As previously mentioned, it is allowed to assume that no other thread is changing it. Therefore, the compiler might optimize that check away, so that is calls std::this_thread::sleep_for
in an infinite loop without ever checking flag
.
Declaring the variable to be atomic will force the compiler to take the possiblity into account that the variable could be modified by another thread at any time. Therefore, the compiler will be prevented from performing any of the optimizations mentioned above and will be forced to reload the variable every time from memory, instead of using a cached copy.
According to the ISO C++ standard, accessing the same memory location by several threads in a non-atomic fashion in which not all threads are read-only will cause undefined behavior. Therefore, the standard requires you to use std::atomic
in such a situation.