2011-09-02 105 views
2

我一直在尋找死鎖和策略/工具的原因,以避免和檢測它們。如何檢測通話?

死鎖的另一個潛在原因是阻塞函數以循環方式調用其他阻塞函數,以致最終調用不會返回。

有時候這很難發現,特別是在非常大的項目中。

那麼,是否有任何工具/庫/技術,可以自動檢測程序中的循環調用?

編輯: 我主要使用C和C++編碼,因此,如果可能,請提供有關適用於這些語言的主題的任何信息。

儘管如此,看起來這個話題幾乎沒有覆蓋在所以,所以其他語言的答案也可以。 雖然也許那些值得自己的話題,如果有人發現它相關

謝謝。

+0

@sbi人們閱讀我們所寫的內容,而不是我們的意思。很公平。另一方面,人們經常在沒有看到他們的情況下看東西。如果你看看我的問題,並且認爲我只是想學習C++,那麼我感到抱歉(這方面的資源比SO好得多)。它現在更新以避免進一步含糊不清。如果你想分享一些關於這個主題的知識,並且幫助我進一步擴展,那對你來說會很好。否則,我感謝你的努力,告訴我可能我選擇了錯誤的地方來提出問題。 – amso

+0

請解釋您是在尋找靜態/編譯時工具還是某種運行時保護/檢測。 –

回答

1

嘗試獲取相同非可重入鎖的循環調用(或遞歸調用)是調試阻塞情況最容易的之一:鎖定是確定性的,並且可以輕鬆檢查。當應用程序鎖定時,啓動調試器並查看堆棧跟蹤以瞭解鎖定的內容以及原因。

至於鎖定問題的一般解決方案...您可以查看一些提供互斥鎖排序的庫,並檢測您何時嘗試鎖定互斥鎖。這種類型的解決方案對於正確實現可能很複雜,但一旦實現,它可以確保您無法輸入死鎖條件,因爲它會強制所有進程以相同的順序獲取鎖(即,如果進程A持有鎖La,並且它嘗試爲了獲得排序正確的鎖Lb,則它可以成功或鎖定,但無論哪個進程正在鎖Lb都不會嘗試鎖定La,因爲排序約束不會被滿足。

1

如果您在Linux上有2個用於檢測死鎖和競態條件的Valgrind工具:Helgrind,DRD。它們都是相輔相成的,值得通過它們來檢查線程錯誤。

0

檢測死鎖(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]; 
    } 
} 
0

你可以找到一個工具,它構建了一個調用圖,並檢查圖形的週期。

否則,有很多檢測死鎖或其他循環的策略,但它們都依賴於某種支持基礎架構。

存在死鎖避免策略,必須根據優先級分配鎖優先級和排序鎖。不過,這些需要更改代碼並執行標準。

+0

是的,我知道使用調用圖。我的目的是找到一種可以使過程自動化的方法。 – amso

+0

您正在尋找靜態/編譯時檢查還是運行時檢查?你願意容忍多少修改你當前的代碼庫? –

+0

運行時檢查會更有用,因爲並不是所有情況都可能被源分析檢測到。它發生我有線程調用函數,在其他線程中執行並阻止調用方,直到「調用」完成。這是一種消息傳遞機制。這些調用不是通過直接函數調用,而是通過將指針傳遞給處理程序來執行。我可以在這些調用中添加一些工具,這些調用將在發佈版本上被禁用。是否有任何種類的儀器可用於此?謝謝。 – amso