#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x,y;
std::atomic<int> z;
void write_x()
{
x.store(true,std::memory_order_seq_cst); // 1
}
void write_y()
{
y.store(true,std::memory_order_seq_cst); // 2
}
void read_x_then_y()
{
while(!x.load(std::memory_order_seq_cst)); // 3
if(y.load(std::memory_order_seq_cst)) // 4
++z;
}
void read_y_then_x()
{
while(!y.load(std::memory_order_seq_cst)); // 5
if(x.load(std::memory_order_seq_cst)) // 6
++z;
}
int main() {
x=false;
y=false;
z=0;
std::thread a(write_x);
std::thread b(write_y);
std::thread c(read_x_then_y);
std::thread d(read_y_then_x);
a.join();
b.join();
c.join();
d.join();
assert(z.load()!=0);
}
In the book C++ Concurrency in Action, the author gives this example when talking about suquential consistency, and says assert
can never fire, because
either [1] or [2] must happen first...and if one thread sees x==true and then subsequently sees y==false, this implies that the store to x occurs before the store to y in this total order.
I understant there is a global total order with all sequentially consistent atomic operations, and if one thread sees x == true, that means operation 1 synchronozies with operation 3, and also happens before 3, but my question is if that thread subsequently sees y == false, why it implies 1 happens before 2? is it possible that operation 2 happens before 1 but operation 4 doesn't see that value change?