簡體   English   中英

原子變量是否無鎖?

[英]Are atomic variables lock-free?

當我們談論原子變量,比如C ++ 11的atomic<> ,它是否可以自由鎖定? 或者鎖定是不同的東西? 如果我使用原子變量管理隊列,它會比無鎖隊列慢嗎?

該標准未指定原子對象是否無鎖。 在不為類型T提供無鎖原子操作的平台上,可以使用互斥鎖來實現atomic<T>對象,該互斥鎖不是無鎖的。 在這種情況下,在其實現中使用這些對象的任何容器也不會是無鎖的。

該標准確實提供了一種檢查atomic<T>變量是否無鎖的方法:您可以使用var.is_lock_free()atomic_is_lock_free(&var) 在給定的程序執行中,這些函數保證始終為相同類型T返回相同的值。 對於諸如int類的基本類型,還提供了宏(例如ATOMIC_INT_LOCK_FREE ),它指定對該類型的無鎖原子訪問是否可用。

無鎖通常適用於多線程之間共享的數據結構,其中同步機制不是互斥的; 目的是所有線程都應該繼續取得某種進展,而不是睡在互斥鎖上。

atomic<T>變量不使用鎖(至少在你的平台上T本身是原子的),但在上面的意義上它們不是無鎖的。 您可以在無鎖容器的實現中使用它們,但它們本身並不足夠。

例如, atomic<queue<T>>不會突然使普通的std::queue進入無鎖數據結構。 但是,您可以實現一個真正無鎖的atomic_queue<T>其成員是atomic

請注意,即使atomic<int>本身是原子的,並且未在您的平台上使用鎖定進行模擬,也不會以任何有趣的方式使其無鎖定 從這個意義上說,Plain int 已經是無鎖的: atomic<>包裝器可以顯式控制內存排序,並可以訪問硬件同步原語。

除了市場營銷和冷卻因素外,無論是神奇的C ++語法(棕色)糖是否最終實現直接總線鎖定或互斥鎖(可能依賴於總線鎖定,但正如評論員指出的那樣),它並沒有產生差別。操作系統內部的優勢是以更有效的方式完成它,或者如果你不幸運行在單處理器架構上,那就什么也不做。

互斥鎖在語義上已經鎖定。 它們在調度程序 - 良好性方面實現了您可能夢寐以求的一切,即優先級反轉處理和重入。 不能在互斥鎖上陷入僵局(實際上,如果你非常努力,你可能會這么做,但就保護變量而言,你不會),並且使用互斥鎖對其他進程不會產生任何明顯的副作用或操作系統比總線鎖定變量。

唯一的區別是程序員可能(通過設計或錯誤地)持有一個互聯網一段不合理的時間,而一個同樣無能的程序員可能會在“無等待”變量上進行輪詢並獲得相同的愚蠢結果,帶來災難性的總線減速會給整個系統帶來更大的壓力,而不是使用有缺陷的互斥鎖(好吧,我之前對BSOD的暗示只是一個少年的挑戰,但我仍然懷疑一些司機可能不會對重型公交車的爭用做出非常友善的反應)。 無論如何,當互斥鎖調用繞過對相當少量內存的線性訪問時,這個問題很快就會解決。

“免費鎖定”正在向wanabee強硬的程序員推銷夢想。 我覺得很有趣的是,可以調用依賴於鎖定多處理器總線的機制。

“無鎖”變量訪問的作用是通過中斷總線緩存系統,禁止總線訪問調度來破壞硬件,並且通常禁用允許平均多處理器總線執行體面工作的所有機制。
每次你訪問“無鎖定”魔法變量時,你都會將一把沙子扔進總線控制器的齒輪中。

與任何並發訪問機制一樣,總線鎖定變量(對不起,我的意思是“鎖定自由變量”)成本高,並且具有潛在的負面影響, 極難預測甚至診斷

只要你使用這些新的閃亮玩具就像你的互斥體一樣,即非常稀疏而且僅僅是出於一些好的理由(而且,沒有,代表超級酷的無等待先生不是其中之一),這很好。

但是,如果你開始在整個地方灑上公共汽車鎖,或者(上帝禁止!) 輪詢公共汽車鎖定變量作為適當同步對象的便宜和容易的替代品(超級酷先生等待的可能稱之為“釀造你自己的自制螺旋鎖通過3個簡單的步驟“),您將只能將代碼運行的任何尖端硬件轉換為大約1995年的Pentium I仿真器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM