簡體   English   中英

如何推斷互斥量組成的正確性?

[英]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 ,但是經過多次測試,它們都具有凍結線程。 我不確定這是我的實現問題還是解決方案本身不正確。

如果您能分析這些解決方案的正確性,我將不勝感激,但我比以往任何時候都更願意學習一種推理此類算法並驗證其正確性的方法。

多次運行您的代碼並希望進行一些任意的交織來發現與並發相關的錯誤不是一個好的方法,但是對於一些初始測試很有用。 否則,有更好的方法。

如果您使用的是C或C ++,則可以查看GCC和Clang中提供的ThreadSanitizer,它將幫助您在運行時檢測死鎖和其他與並發相關的錯誤。

更詳盡的方法是系統並發測試,該測試將枚舉可能的交錯並執行它們。 您應該檢出不同的技術,例如無狀態和有狀態模型檢查。

Spin是一種模型檢查工具,可用於形式驗證。 您可以在Promela中編寫模型,並使用LTL進行斷言。

最后,這是Wikipedia的各種語言的模型檢查器列表

關於lockdep的文檔(例如: https ://lwn.net/Articles/705379/)是描述您正在尋找的一般標准的眾多資源之一:您希望實現在依賴關系圖中沒有循環。

d鎖定兩次的示例中,您有一個依賴圖,該圖的循環僅由一個節點d ,邊沿返回自身。

一種可能對解決方案3和4有所幫助的多線程編碼樣式是,始終以與獲取鎖相反的順序釋放鎖。 在紙上解決問題的總體理解可能會有所幫助,為什么在您的代碼上強加此要求至少與說您的實現不需要在其依賴圖中沒有循環這樣嚴格。

還有一個額外的問題:是否有實現中鎖和釋放的順序不是鏡像,但仍然沒有循環?

暫無
暫無

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

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