理解原子变量之五:指令重排、memory_order__acquire与memory_order_release

理解原子变量之五:指令重排、memory_order__acquire与memory_order_release 看下面代码#include iostream #include thread #include assert.h #include atomic int a 0; std::atomicbool flag{ false }; void f1() { a 1; flag.store(true, std::memory_order_release); //flag.store(true, std::memory_order_relaxed); } void f2() { while (!flag.load(std::memory_order_acquire)) //while (!flag.load(std::memory_order_relaxed)) { } assert(a 1); } int main(void) { std::thread t2(f2); std::thread t1(f1); t1.join(); t2.join(); return 0; }1 memory_order_release要求在调用memory_order_release之前的所有写操作不得重排到memory_order_release之后。在上面的代码里显然a 1就是写入。2 memory_order_acquire要求在调用memory_order_acquire之后的所有读操作不得重排到memory_order_acquire之前。在上面的代码里a 1是对a当前值的判断当然属于读操作。3 结合1与2函数f2的while循环直到flag true才会跳出所以跳出之前f1一定已经将flag.store执行完毕了。那么根据(1)的要求a1的操作肯定发生在flag.store之前。于是while()循环结束后a1的操作一定已经发生了。再结合上一篇理解原子变量之四可见性、memory_order_acquire与 memory_order_release_memory order acquire-CSDN博客的可见性a的改变一定可以对此时的线程t2可见。最后根据(2)的要求assert(a 1)一定发生在while之后因为里面含有flag.load(memory_order_acquire)。所以assert(a 1)一定可以看到a 1为真。最后建议读一下微信公众号“程序喵大人”的文章《【C并发系列】第五章C 内存模型在约束什么》里面的描述更加全面。