2017-10-04 159 views
-3

我創建了兩個用C代碼編寫的線程,它在Linux操作系統上運行。這兩個線程都在做一些工作,並且它的父進程還在運行時會永久運行。如何知道線程是否處於死鎖狀態?

創建這些線程的過程是以一定的時間間隔向systemd發送一個看門狗通知。但是,在發送看門狗通知之前,它想要檢查所有線程是否處於非死鎖狀態。

在代碼中可以使用哪種系統調用,或者可以使用哪種機制來知道線程不處於死鎖狀態,以便進程可以檢查其創建的線程是否處於死鎖狀態,並且只發送如果所有線程都處於非死鎖狀態,則向systemd發送看門狗通知。

+1

當線程即將獲取系統資源時,爲父線程存儲時間戳。當線程獲取系統資源時,使時間戳無效。如果父線程看到時間戳超過某個限制,它可以聲明系統已死鎖。 – user3386109

+0

通過爲父線程存儲時間戳,你的意思是什麼?父線程如何知道該子線程即將獲取系統資源。請您分享一個示例示例來實現我的目標 –

+0

操作系統無法以任何有效的方式確定此示例。您需要在您的應用設計中進行這樣的檢查,如果您需要,可以設計它,並且如果可以實現它,而不會引入比解決問題更多的問題。 –

回答

1

最簡單的方法是讓每個需要跟蹤的線程定期更新自己的共享變量。監控包括檢查共享變量的值是否經常變化。

考慮一個類比。你經常不在家,但你想確保你的兩個孩子沒有失蹤。所以你每個孩子都有一個罐子。你告訴他們每次回家時都要給罐子加一分錢。現在,每次你回家的時候,你都會在每個罐子裏計數幾分錢。如果任何孩子的罐子的硬幣數量相同時間過長,則知道您有問題。

因此,舉例來說,你可以修改每個線程做的工作:

  1. 做一些工作。
  2. 轉到1

要:

  1. 做一些工作。
  2. 遞增我的進度變量。
  3. 轉到步驟1

則監控線程只是要跟蹤它最後一次看到了狀態變量和當前值不同的值。然後,它可以按如下方式檢測死鎖線程:

  1. 在我們正在監視的每個線程上循環。
  2. 其狀態變量是否與上次不同?如果不是,請轉至步驟5.
  3. 存儲我們看到的其狀態變量的值並存儲當前時間。
  4. 繼續我們在步驟1中開始的循環。
  5. 我們爲此線程的上次更新存儲了過去的時間嗎?如果是這樣,報告一個僵局。
  6. 繼續我們在步驟1中開始的循環。
+0

我認爲第二宗案件適用於部分案件。讓我們假設,線程調用select in loop並且線程處於阻塞狀態。只有選擇獲取信號,然後只有'狀態變量'被更新,它纔會繼續循環。正在以某個間隔監視此線程的主線程將獲得舊狀態變量值,因爲在主線程正在檢查狀態變量的那個時間間隔內沒有觸發select,因爲主線程檢查它保留了舊值,但它報告了死鎖線程不處於死鎖狀態。 –

+0

@VikashRanjan您必須在'select'中設置合適的超時時間。否則,將一個管道末端添加到'select'集合並讓監視線程使用它來觸發。是的,這必須嵌入到設計中 - 它不會隨意灑在頂部。 –

+0

@VikashRanjan閱讀我的答案。這正是我所解釋的。設計線程以便每隔一段時間遞增一個狀態變量,如果它沒有改變,則會死鎖。 –

相關問題