我一直在尋找死鎖和策略/工具的原因,以避免和檢測它們。如何檢測通話?
死鎖的另一個潛在原因是阻塞函數以循環方式調用其他阻塞函數,以致最終調用不會返回。
有時候這很難發現,特別是在非常大的項目中。
那麼,是否有任何工具/庫/技術,可以自動檢測程序中的循環調用?
編輯: 我主要使用C和C++編碼,因此,如果可能,請提供有關適用於這些語言的主題的任何信息。
儘管如此,看起來這個話題幾乎沒有覆蓋在所以,所以其他語言的答案也可以。 雖然也許那些值得自己的話題,如果有人發現它相關
謝謝。
我一直在尋找死鎖和策略/工具的原因,以避免和檢測它們。如何檢測通話?
死鎖的另一個潛在原因是阻塞函數以循環方式調用其他阻塞函數,以致最終調用不會返回。
有時候這很難發現,特別是在非常大的項目中。
那麼,是否有任何工具/庫/技術,可以自動檢測程序中的循環調用?
編輯: 我主要使用C和C++編碼,因此,如果可能,請提供有關適用於這些語言的主題的任何信息。
儘管如此,看起來這個話題幾乎沒有覆蓋在所以,所以其他語言的答案也可以。 雖然也許那些值得自己的話題,如果有人發現它相關
謝謝。
嘗試獲取相同非可重入鎖的循環調用(或遞歸調用)是調試阻塞情況最容易的之一:鎖定是確定性的,並且可以輕鬆檢查。當應用程序鎖定時,啓動調試器並查看堆棧跟蹤以瞭解鎖定的內容以及原因。
至於鎖定問題的一般解決方案...您可以查看一些提供互斥鎖排序的庫,並檢測您何時嘗試鎖定互斥鎖。這種類型的解決方案對於正確實現可能很複雜,但一旦實現,它可以確保您無法輸入死鎖條件,因爲它會強制所有進程以相同的順序獲取鎖(即,如果進程A持有鎖La,並且它嘗試爲了獲得排序正確的鎖Lb,則它可以成功或鎖定,但無論哪個進程正在鎖Lb都不會嘗試鎖定La,因爲排序約束不會被滿足。
檢測死鎖(IMO)的最佳方法是製作一個測試程序,以30個不同的線程10000s的次數隨機地調用所有函數。
如果遇到死鎖,可以使用VS2010「Parallel Stacks」窗口。 Debug-> Windows-> Parallel Stacks
這個窗口會顯示所有的堆棧,所以你可以找到死鎖的方法。
一個簡單的策略,我用它來編寫線程安全的對象:
線程安全的對象應該是安全的被稱爲它的公共方法時,所以在使用時你沒有得到死鎖。
所以,這個想法是鎖定所有訪問對象數據的公共方法。
除此之外,您需要確保在班級代碼中您永遠不會調用公開方法。如果您需要使用其中一種公共方法,請將該方法設爲私有方法,然後使用公用方法包裝私有方法,然後鎖定並調用該方法。
如果你想要更好的鎖定粒度,你可以爲每個擁有自己的鎖的零件創建對象,並像我建議的那樣鎖定它。然後使用封裝將這些類組合到一個類中。
例子:
class Blah {
MyData data;
Lock lock;
public:
DataItem GetData(int index)
{
ReadLock read(lock);
return LocalGetData(index);
}
DataItem FindData(string key)
{
ReadLock read(lock);
DataItem item;
//find the item, can use LocalGetData() to get the item without deadlocking
return item;
}
void PutData(DataItem item)
{
ReadLock write(lock);
//put item in database
}
private:
DataItem LocalGetData(int index)
{
return data[index];
}
}
你可以找到一個工具,它構建了一個調用圖,並檢查圖形的週期。
否則,有很多檢測死鎖或其他循環的策略,但它們都依賴於某種支持基礎架構。
存在死鎖避免策略,必須根據優先級分配鎖優先級和排序鎖。不過,這些需要更改代碼並執行標準。
@sbi人們閱讀我們所寫的內容,而不是我們的意思。很公平。另一方面,人們經常在沒有看到他們的情況下看東西。如果你看看我的問題,並且認爲我只是想學習C++,那麼我感到抱歉(這方面的資源比SO好得多)。它現在更新以避免進一步含糊不清。如果你想分享一些關於這個主題的知識,並且幫助我進一步擴展,那對你來說會很好。否則,我感謝你的努力,告訴我可能我選擇了錯誤的地方來提出問題。 – amso
請解釋您是在尋找靜態/編譯時工具還是某種運行時保護/檢測。 –