![](/img/trans.png)
[英]Correctness of using std::atomic<bool> in combination with std::mutex
[英]How to reason the correctness of mutex composition?
我正在嘗試使用互斥量實現信號量,以了解有關並發基元和模式以及如何編寫正確的並發程序的更多信息。
這是我找到的資源: http : //webhome.csc.uvic.ca/~mcheng/460/notes/gensem.pdf
第9頁上的解決方案#1標記為“不正確”。我在此處實現了該算法。 多次運行該程序可能會導致線程凍結。 我做了一些分析,意識到在d
互斥鎖上可能發生以下操作序列:
// d was initialized as locked
d.unlock(); // d is unlocked
d.unlock(); // d is still unlocked (unaffected)
d.lock(); // d is locked
d.lock(); // d is still locked (deadlock)
這將導致最后的d.lock()
死鎖。
解決方案#2通過重用互斥鎖m
確保從信令線程到喚醒線程的過渡,從而解決了此問題。 我在這里實現了這個版本。
在此解決方案中,在d.unlock()
, m
保持鎖定,這意味着后續的post()
操作將被阻塞,直到m
被解鎖。 然后,在d.lock()
調用m.unlock()
,確保d
處於鎖定狀態,然后再運行后續的post()
操作。
盡管我了解此解決方案如何解決該問題,但我很難在其他潛在問題上爭論其正確性。 我們是否可以遵循任何一般性規則和指南來確保,爭論甚至證明此類程序的正確性?
我想問這個問題,因為注釋中的下2個解決方案。 我實現了解決方案3和解決方案4 ,但是經過多次測試,它們都具有凍結線程。 我不確定這是我的實現問題還是解決方案本身不正確。
如果您能分析這些解決方案的正確性,我將不勝感激,但我比以往任何時候都更願意學習一種推理此類算法並驗證其正確性的方法。
關於lockdep的文檔(例如: https ://lwn.net/Articles/705379/)是描述您正在尋找的一般標准的眾多資源之一:您希望實現在依賴關系圖中沒有循環。
在d
鎖定兩次的示例中,您有一個依賴圖,該圖的循環僅由一個節點d
,邊沿返回自身。
一種可能對解決方案3和4有所幫助的多線程編碼樣式是,始終以與獲取鎖相反的順序釋放鎖。 在紙上解決問題的總體理解可能會有所幫助,為什么在您的代碼上強加此要求至少與說您的實現不需要在其依賴圖中沒有循環這樣嚴格。
還有一個額外的問題:是否有實現中鎖和釋放的順序不是鏡像,但仍然沒有循環?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.