![](/img/trans.png)
[英]How compiler like GCC implement acquire/release semantics for std::mutex
[英]Release/Acquire semantics wrt std::mutex
我正在閱讀n3485中定義的C ++內存模型,它討論了發布/獲取語義,根據我的理解,以及本博客中給出的定義:
收購語義是它只能適用於從共享內存中讀取 ,無論是讀-修改-寫操作或普通負載操作的性能。 然后該操作被認為是讀取。 獲取語義可防止讀取采集的內存重新排序,並按程序順序執行任何讀取或寫入操作。
發布語義是一種屬性,它只能應用於寫入共享內存的操作,無論它們是讀取 - 修改 - 寫入操作還是普通存儲。 然后將該操作視為寫入釋放。 釋放語義通過程序順序中的任何讀取或寫入操作來防止寫入釋放的內存重新排序。
將阻止在當前讀/寫完成之前或之后重新排序讀/寫。 第一個(獲取)將確保當前正在執行的讀取不會在其之后的任何讀/寫重新排序,后者(發布)將確保當前寫入未使用之前的讀/寫操作重新排序它。
現在可以說std::mutex::lock
將具有獲取語義,並且std::mutex::unlock
基本上具有發布語義?
在標准中,我可以在部分下找到它
30.4.1.2互斥體類型[thread.mutex.requirements.mutex]
11同步:對同一對象的先前
unlock()
操作應與 (1.10)此操作同步 。
從我理解的同步並沒有在標准中明確定義,但它似乎是在關系看兩個不同線程之間評估的兩個語句之前發生的類型,但是,根據我對獲取/釋放語義的理解,這有更多與記憶重新排序有關。 同步也可以稱為發布/獲取語義?
那么發布/獲取語義是否不僅適用於加載/存儲操作的重新排序以及操作的線程內交錯?
在關於內存模型的標准部分中,它主要討論了兩個線程交錯的有序關系。 這可以解釋這是否也適用於內存排序。
任何人都可以澄清一下嗎?
現在可以說std :: mutex :: lock將具有獲取語義,並且std :: mutex :: unlock基本上具有發布語義?
是的 ,這是正確的。
據我所知, 同步並未在標准中明確定義
那么,理論上第1.10 / 8段可能是為了給出與以下內容同步的定義:
某些庫調用與另一個線程執行的其他庫調用同步 。 例如,原子存儲釋放與從存儲獲取其值的load-acquire 同步 (29.3)。 [注意: ...]
另一方面,這聽起來不像是一個非常正式的定義。 然而,在第1.10 / 10段中間接給出了一個更好但隱含的更好的方法:
在評估B if 之前 ,評估A是依賴性排序的
- A對原子對象M執行釋放操作,並且在另一個線程中,B對M執行消耗操作並讀取由A標記的釋放序列中的任何副作用寫入的值,或者
- 對於某些評估X,A在X之前是依賴排序的,而X對B具有依賴性。
[注意: 關系“依賴於順序排序”類似於“與...同步”,但使用release / - 代替釋放/獲取。 - 尾注]
由於“ 類似於 ”關系通常是對稱的,我會說上面的“ is-dependency-ordered before ”的定義間接提供了“ 同步 ”的定義 - 盡管你可能正確地反對那些注釋是非-normative; 不過,這似乎是預期的定義。
我對與關系同步的直覺是它發生在一個存儲某個值的線程執行的寫(原子)操作和讀取該值的第一個 (原子)操作之間。 該操作也可能在同一個線程中。
如果兩個操作在不同的線程上,則synchronize-with關系在操作上建立跨線程排序。
在標准中,我可以在部分下找到它
30.4.1.2互斥體類型[thread.mutex.requirements.mutex]
11同步:對同一對象的先前
unlock()
操作應與 (1.10)此操作同步 。
對我來說,這似乎與上面給出的解釋兼容。 具有釋放語義(解鎖,存儲)的操作將與獲取語義(鎖定,加載)的操作同步。
但是,根據我對獲取/釋放語義的理解,這更多地與內存重新排序有關。 同步也可以稱為發布/獲取語義?
釋放和獲取語義描述了某些操作的本質; 同步關系(實際上)是以明確定義的方式在具有獲取或釋放語義的操作之間建立的關系 。
因此,在某種意義上, synchronize-with是這些操作的語義的結果,我們使用這些語義來實現指令的正確排序並約束CPU或編譯器將執行的可能的重新排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.