Before asking this question I tried set my VM cores to more than 1(I set it to 2), according to suggestion from this question, this solution worked for the author, but not for me.
The book C++ Concurrency in Action gives an example in Listing 5.5
#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x,y;
std::atomic<int> z;
void write_x_then_y()
{
x.store(true,std::memory_order_relaxed); // 1
y.store(true,std::memory_order_relaxed); // 2
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed)); // 3
if(x.load(std::memory_order_relaxed)) // 4
++z;
}
int main()
{
for(int i = 0; i < 1000; i++){
// this loop is addeed by me in order to try 1000 times to see whether the assertion will fail
x=false;
y=false;
z=0;
std::thread a(write_x_then_y);
std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load()!=0); // 5
}
}
The book says the assertion assert(z.load()!=0)
may fail. However, I can't fail this assertion when testing.
I tested the program by 64-bit Ubuntu(under VMWare), g++ -g -o test --std=c++17 test.cpp -lpthread
, I tested under both gcc 5.4.0 and gcc 7.2.0.
I also tested the program by 64-bit Windows 10(not in a VM), Visual studio 2015.
Meanwhile, by searching the internet, I saw some people say this is because of the x86 architecture, however, I remember in x86, Loads may be reordered with older stores to different locations, so I think there can be a order 2-3-4-1
which can fail this assertion.