C 執行緒的學習 執行緒死鎖

2022-06-16 15:39:09 字數 1108 閱讀 3654

因為是學習篇,寫下是為了個人的學習與理解。故參考其他文章為多。

想象一下這樣的情況,thread a 在run的時候需要等待thread b的結果,也就是threadproca中新增tb.join(), 在thread b的threadprocb中新增ta.join()。結果就是執行緒a在死等執行緒b的結果,而執行緒b也在死等執行緒a的結果。這樣就造成了死鎖。

另乙個例子: 兩個執行緒爭互斥鎖:每乙個執行緒需要去鎖定一對互斥鎖(mutex)去執行乙個任務,乙個執行緒已經獲取了乙個互斥鎖(mutex),另乙個也獲取了乙個互斥鎖(mutex),每乙個執行緒都在等待鎖定另乙個互斥鎖(mutex),這樣造成的結果是任何乙個執行緒都無法得到另乙個互斥鎖(mutex)。這種就叫死鎖(deadlock),這裡最大的問題是完成任務必須鎖定兩個或多個互斥鎖(mutex)來執行操作。

執行緒死鎖只發生在有鎖的情況下。有時你建立了兩個個執行緒,這兩個執行緒分別join另乙個執行緒,這樣任何join都無法返回,每個執行緒都在等待另乙個執行緒結束,這就是兩個孩子為了玩具打架一樣。這種的問題可以發生在任何「乙個執行緒正在等另乙個執行緒做事,而另乙個執行緒有時候也會等第乙個執行緒做什麼事」的時候。避免執行緒死鎖歸結為乙個重要概念就是:a執行緒不要等待b執行緒,如果b執行緒有可能等待a執行緒。

避免巢狀鎖定

這一條是最簡單的,你已經鎖定了乙個mutex的時候,你最好不要再次鎖定。如果你遵守了這條規則,因為乙個執行緒只有乙個鎖的情況下不會造成死鎖。但是也有其它原因會造成死鎖(比如乙個執行緒在等待另乙個執行緒),如果你要鎖定多個,你就用std::lock。

2. 在已經持有鎖的時候不要呼叫使用者自義的**

因為使用者自定義的**是無法預知的,誰知道他的**裡會不會也想要鎖定這個lock。有時候無法避免不呼叫使用者定義**,這種情況下,你需要注意。

3. 按固定順序鎖定

如果你要鎖定兩個以上的mutex而你又不能用std::lock。那麼最好的建議就按固定順序去鎖定。

4. 用層鎖來防止死鎖

hierarchical_mutex規則思想是:將mutex分層,規定加鎖順序是由高層到底層才能進行,底層到高層報出執行時錯誤,這樣就可以利用程式設計的方法檢測死鎖。

文章參考: c++多執行緒-執行緒中的死鎖問題

C 多執行緒 死鎖

相信有過多執行緒程式設計經驗的朋友,都吃過死鎖的苦。除非你不使用多執行緒,否則死鎖的可能性會一直存在。為什麼會出現死鎖呢?我想原因主要有下面幾個方面 1 個人使用鎖的經驗差異 2 模組使用鎖的差異 3 版本之間的差異 4 分支之間的差異 5 修改 和重構 帶來的差異 不管什麼原因,死鎖的危機都是存在...

C 多執行緒死鎖

死鎖問題被認為是執行緒 程序間切換消耗系統效能的一種極端情況。在死鎖時,執行緒 程序間相互等待資源,而又不釋放自身的資源,導致無窮無盡的等待,其結果是任務永遠無法執行完成。死鎖出現的場景 當 中有2個鎖,鎖a和鎖b,也有2個執行緒,執行緒1和執行緒2,執行緒1執行時,先搶到鎖a,然後要去搶占b,同時...

執行緒的死鎖

如果乙個程序集合裡面的每個程序都在等待這個集合中的其他乙個程序 包括自身 才能繼續往下執行,若無外力他們將無法推進,這種情況就是死鎖,處於死鎖狀態的程序稱為死鎖程序 乙個簡單的死鎖類 當deadlock類的物件flag 1時 td1 先鎖定o1,睡眠500毫秒 而td1在睡眠的時候另乙個flag 0...