2012-12-03 157 views
1

(這個問題可能與pthread_exit in signal handler causes segmentation fault有些相關)我正在寫一個leadlock預防庫,其中總是有一個檢查線程在做圖形的東西,並檢查是否存在死鎖,如果是的話,它會發出信號其中一個衝突線索。當該線程捕獲該信號時,它釋放它擁有並退出的所有互斥鎖。有多個資源互斥體(顯然)和一個關鍵區域互斥體,所有獲取,釋放資源鎖定和執行圖形計算的調用都必須先獲得此鎖定。現在出現了這個問題。與2競爭(不包括檢查線程)線程,有時程序在一個線程被終止後死鎖。在gdb中,它表示死亡線程擁有臨界區域鎖定,但從未釋放它。在信號處理程序中添加了中斷點並逐步完成之後,看來,鎖在pthread_exit()之前屬於其他人(如預期的那樣),但所有權在pthread_exit()之後神奇地轉到此線程。

唯一的猜測我可以想象的是,當嘗試獲取臨界區鎖(因爲它想要另一個資源互斥鎖)時,要被殺死的線程在pthread_mutex_lock處被阻塞,然後信號到達,中斷pthread_mutex_lock。由於這次通話不是信號證明,發生了一些奇怪的事情?就像信號處理程序可能已經返回並且該線程獲得了鎖然後退出? Idk ..任何見識都被讚賞!pthread_exit()在信號處理程序

+0

誰將週期檢查器與競賽條件鎖定?你是否以某種方式獲得了鎖定收購任何鎖?定時器可以在任何時候執行,信號處理程序可以中斷包括'pthread_mutex_lock'在內的任何事情(即使它不是*阻塞)。我不知道Linux提供什麼具體措施來解決這個問題,但你可能會提到你所做的。 – Potatoswatter

+0

看看下面的鏈接可以幫助你:(1)http://stackoverflow.com/questions/13305422/how-to-kill-the-management-thread-with-c(2)http://stackoverflow.com/questions/13309415/how-to-execute-a-handler-function-before-quit-the-program-when-receiving-kill-si – MOHAMED

+0

@Potatoswatter不確定如果我完全理解你的問題,檢查器只會獲取cr鎖,檢查資源圖中的週期,如果是,則表示某人死亡並返回睡眠1秒。就是這樣。具體來說,在測試案例中,我有2個線程和2個資源互斥,競爭條件確實發生,但更糟糕的情況下,檢查器會在1秒後發現並殺死某人。這確實有用,偶爾.. – lzt

回答

3

pthread_exit不是異步信號安全的,因此您可以從信號處理程序調用它的唯一方法是確保信號不中斷任何非異步信號安全函數。

作爲一般原則,使用信號作爲與線程通信的方法通常是一個非常糟糕的主意。您最終將兩個已經足夠困難的問題混合在一起:線程安全(線程之間的正確同步)和單線程內的重入。

如果你的信號目標只是指示線程終止,更好的機制可能是pthread_cancel。然而,爲了安全使用這個功能,將被取消的線程必須在正確的位置設置取消處理程序,和/或在不安全的情況下暫時取消取消(使用pthread_setcancelstate)。此外,請注意pthread_mutex_lock不是取消點。有沒有安全的方式來中斷一個被阻塞的線程,等待獲得一個互斥量,所以如果你需要這樣的中斷能力,你可能需要一個更精細的同步設置與條件變量(condvar等待是可取消的),或者你可以使用信號量而不是互斥體。

編輯:如果你真的需要一種方法來終止線程等待互斥體,你可以通過調用自己的函數調用迴路和pthread_mutex_timedlock檢查每個超時的情況下出口標誌更換呼叫pthread_mutex_lock