⑥ 会不会发生,看 CPU 允许哪些乱序
后读的 data 比先读的 ready 还旧,这是读和读乱序(LoadLoad)。x86 不允许它,硬件保证 ⑥ 读到 42。ARM 允许:读 ready 要用 acquire,后面的读才会等失效处理完。ARM 还允许两个写乱序(StoreStore),ready 可能先于 data 被别的核看见,所以写 ready 要用 release。x86 上这段代码也是错的:ready 不是 atomic,编译器可以把循环里的读提到循环外,或者调换两个写。修法:std::atomic<bool> ready,写 release,读 acquire。