std::memory_order specifies how regular, non-atomic memory accesses are to be ordered around an atomic operation. 因此,對於兩個併發的原子操作,不論指定的是哪種memory order,它們的執行肯定是原子的。但是考慮下面修改後的例子,memory order就有意義了。當引入另外一個全域性共享變數b以後,執行緒1在a.fetch_add之前把b寫入5,執行緒2在讀取到x為1的情況下(也就是說執行緒2的fetch_add發生線上程1的fetch_add之後)讀出的b值不一定等於5。這是因為現代處理器對沒有依賴的讀寫操作可能會進行亂序執行。不強制指定memory order的話,沒有辦法保證b=5這個寫入操作確確實實發生在a.fetch_add之前。C++的memory order就是為了在這一類情況下給程式設計師控制記憶體讀寫順序的。如果要保證執行緒2在讀到x為1時必然能觀察到執行緒1寫入的b值,那我們就要用到如下的記憶體順序引數。memory_order_release確保了執行緒1在進行原子操作前所有寫在前面的非原子記憶體寫入都已經完成了, memory_order_acquire確保了執行緒2不能把任何寫在原子操作之後的非原子記憶體讀取亂序到原子操作之前執行。這樣的話執行緒2讀到x為1時,必然讀到b為5。關於C++其他的記憶體順序,詳細的可以進一步參考std::memory_order。另外,在C++11記憶體模型出來以前,大家是手寫memory barrier來強制記憶體讀寫順序的,詳見Memory barrier。
C++裡的memory order是用來指定原子操作(atomic operation)和同執行緒內其他非原子操作之間的執行順序的。
std::memory_order specifies how regular, non-atomic memory accesses are to be ordered around an atomic operation. 因此,對於兩個併發的原子操作,不論指定的是哪種memory order,它們的執行肯定是原子的。但是考慮下面修改後的例子,memory order就有意義了。當引入另外一個全域性共享變數b以後,執行緒1在a.fetch_add之前把b寫入5,執行緒2在讀取到x為1的情況下(也就是說執行緒2的fetch_add發生線上程1的fetch_add之後)讀出的b值不一定等於5。這是因為現代處理器對沒有依賴的讀寫操作可能會進行亂序執行。不強制指定memory order的話,沒有辦法保證b=5這個寫入操作確確實實發生在a.fetch_add之前。C++的memory order就是為了在這一類情況下給程式設計師控制記憶體讀寫順序的。如果要保證執行緒2在讀到x為1時必然能觀察到執行緒1寫入的b值,那我們就要用到如下的記憶體順序引數。memory_order_release確保了執行緒1在進行原子操作前所有寫在前面的非原子記憶體寫入都已經完成了, memory_order_acquire確保了執行緒2不能把任何寫在原子操作之後的非原子記憶體讀取亂序到原子操作之前執行。這樣的話執行緒2讀到x為1時,必然讀到b為5。關於C++其他的記憶體順序,詳細的可以進一步參考std::memory_order。另外,在C++11記憶體模型出來以前,大家是手寫memory barrier來強制記憶體讀寫順序的,詳見Memory barrier。