簡體   English   中英

了解並避免多線程應用程序中嵌套鎖的危險

[英]Understanding and avoiding the dangers of nested locks in multithreaded applications

對於多線程我還是很陌生,但是已經被燒了好幾次了。 現在,我嘗試避免一些陷阱,但是我很難做到以下幾點:

考慮幾個線程,線程A生產者,因此是writer ,線程BC ,...消費者線程,因此是reader 全部共享一個公共緩沖區S

一些基礎書籍建議針對這種情況引入一個所謂的ReadWriteLock 可以進行多個並發讀取,但顯然只有一次寫入。Boost也提供了這樣的鎖,Qt也是如此。

讓我們假設兩個函數f1和f2鎖定S進行讀取。 在線程B中,調用f1並讀取鎖定,而在f1內調用f2再次讀取鎖定 ,因此可以進行嵌套鎖定

現在考慮執行f1並首次鎖定讀取的瞬間。 如果線程A被調用並想寫,他將被阻塞。 另外,如果里面F1 F2被調用,並希望將其鎖定不能因為阻塞writer在等待,在這種情況下,許多鎖(如QReadWriteLock )阻止進一步的readers也是如此。 因此,我們得到一個非常討厭的死鎖,該死鎖是無法預測的,並且僅當writer在f1的鎖和f2的鎖之間插入時才會發生。

我當前避免此類錯誤的方法是調試工具,該工具跟蹤鎖定並斷言同一線程是否試圖鎖定兩次以進行讀取,但這非常麻煩。 除此之外,我避免將太多代碼放在鎖中,這雖然有幫助,但我的團隊的其他成員可以忽略它。

還有什么其他功能可以用來防止這種情況? 為什么ReadWriteLocks完全允許它們? 在設計階段是否有一些通用的經驗法則可以避免上述情況?

預先感謝您閱讀冗長的問題;-)

也許您可以使用QReadWriteLock的tryReadLock函數。 防止死鎖。

如果它無法鎖定讀取文件,則解鎖讀取互斥鎖。

在某些情況下,它可能會丟失要讀取的數據,如果您不想丟失任何要讀取的數據,則可以通過放置標志或ID號或標識失敗的讀取作業並將其放入堆棧的方式來解決,因此寫線程完成工作后,您將能夠從失敗的內容開始恢復讀的內容。 它將使您最大程度地減少數據丟失。

我希望這會有所幫助。

抱歉我的英語不好。

暫無
暫無

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

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