c++11 atomic中的6種 momey order
memory_order_relaxed: 只提供對單個atomic變量的原子讀/寫,不和前后語句有任何memory order的約束關(guān)系. 一般只用來做普通計數(shù)器感猛,引用計數(shù)都不能做⊙罚可能導致別打cpu看不到最新的數(shù)據(jù)變化而產(chǎn)生錯誤的虛構(gòu)行為。
memory_order_release memory_order_consume:thread A 對變量x release。thread B 對變量x consume荞胡。那么thread A對依賴x所有的寫操作糊探,對thread B依賴x的讀操作都收可見的挎狸。
memory_order_release memory_order_acquire: thread A 執(zhí)行release扣汪, thread B執(zhí)行acquire断楷。那么thread A 在release之前的所有寫操作锨匆,對thread B acquire后任何讀操作,都是可見的。
即 release執(zhí)行的操作 不能reorder到release之后恐锣。acquire 之后的操作茅主,不能reorder到acquire之前。
memory_order_acq_rel:是memory_order_acquire和memory_order_release的合并土榴,這條語句前后的語句都不能被reorder
memory_order_seq_cst :比memory_order_acq_rel更加嚴格的順序保證诀姚,memory_order_seq_cst執(zhí)行完畢后,所有其cpu都是確辩枨荩可以看到之前修改的最新數(shù)據(jù)的赫段。如果前面的幾個memory order模式允許有緩沖存在的話,memory_order_seq_cst指令執(zhí)行后則保證真正寫入內(nèi)存矢赁。一個普通的讀就可以看到由memory_order_seq_cst修改的數(shù)據(jù)糯笙,而memory_order_acquire則需要由memory_order_release配合才能看到,否則什么時候一個普通的load能看到memory_order_release修改的數(shù)據(jù)是不保證的撩银。
x86的memory order是一種strong memory order给涕,它保證:
LoadLoad是順序的
一個cpu上前后兩條load指令是順序執(zhí)行的,前面一條沒執(zhí)行完畢额获,后面一條不能執(zhí)行
StoreStore是順序的
一個cpu上前后兩條store指令是順序執(zhí)行的够庙,前面一條沒執(zhí)行完畢,后面一條不能執(zhí)行
LoadStore
一個cpu上前面一條是Load指令抄邀,這條指令沒執(zhí)行完畢耘眨,后面一條store不能執(zhí)行
x86不保證StoreLoad的順序,一條Store指令在前境肾,后面一條不相關(guān)的load指令可以先執(zhí)行毅桃。因為這個順序的不保證,導致Peterson lock實際上需要使用mfence指令才能在x86上實現(xiàn)