C 的 3种内存顺序,你都知道吗?
1、std::memory_order_relaxed “自由”內(nèi)存順序
在原子類型上的操作以自由序列執(zhí)行,沒有任何同步關(guān)系,僅對此操作要求原子性。例如,在某一線程中,先寫入A,再寫入B。但是在多核處理器中觀測到的順序可能是先寫入B,再寫入A。自由內(nèi)存順序?qū)τ诓煌兞靠梢宰杂芍嘏判颉?/p>
這是因為不同的CPU緩存和內(nèi)部緩沖區(qū),在同樣的存儲空間中可以存儲不同的值。對于非一致排序操作,線程沒有必要去保證一致性。
上述代碼,z.load()!=0有可能會返回false。在b線程中,多核處理器觀測到的順序是隨機的。b線程中的觀測到的變量的并不會與線程a中的變量做同步,沒有任何順序要求。
2、std::memory_order_release “釋放”內(nèi)存順序
使用memory_order_release的原子操作,當前線程的讀寫操作都不能重排到此操作之后。例如,某一線程先寫入A,再寫入B,再以memeory_order_release操作寫入C,再寫入D。在多核處理器中觀測到的順序AB只能在C之前,不能出現(xiàn)C寫入之后,A或B再寫入的情況。但是,可能出現(xiàn)D重排到C之前的情況。
memory_order_release用于發(fā)布數(shù)據(jù),放在寫操作的最后。
3、std::memory_order_acquire “獲取”內(nèi)存順序
使用memory_order_acquire的原子操作,當前線程的讀寫操作都不能重排到此操作之前。例如,某一線程先讀取A,再讀取B,再以memeory_order_acquire操作讀取C,再讀取D。在多核處理器中觀測到的順序D只能在C之前,不能出現(xiàn)先讀取D,最后讀取C的情況。但是,可能出現(xiàn)A或B重排到C之后的情況。
memory_order_acquire用于獲取數(shù)據(jù),放在讀操作的最開始 。
上述代碼是使用“釋放-獲取"模型對“自由”模型的改進。z.load() != 0 返回的一定是true。首先,a線程中,y使用memory_order_release釋放內(nèi)存順序,在多核處理器觀測到的順序,x的賦值肯定會位于y之前。b線程中,y的獲取操作是同步操作,x的訪問順序必定在y之后,觀測到的x的訪問值一定為true。
“獲取”與“釋放”一般會成對出現(xiàn),用來同步線程。
聲明:
本文于網(wǎng)絡整理,版權(quán)歸原作者所有,如來源信息有誤或侵犯權(quán)益,請聯(lián)系我們刪除或授權(quán)事宜。
總結(jié)
以上是生活随笔為你收集整理的C 的 3种内存顺序,你都知道吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票龙回头如何买入?
- 下一篇: C 常见的面试知识点(上)