1. 程式人生 > >關於執行緒與訊號處理函式獲得同一把互斥鎖的問題 (原)

關於執行緒與訊號處理函式獲得同一把互斥鎖的問題 (原)

轉發請註明出處:http://www.cppblog.com/mysileng/admin/EditPosts.aspx?postid=196971
    剛寫了程式發現點問題。假設一個程式有多個執行緒,有一個全域性互斥鎖M....在某執行緒A獲得鎖以後,這個時候來了一個訊號(假設這個訊號註冊了自己的處理程式),那麼需要進入訊號處理程式,進入以後訊號處理處理程式也要獲得這個鎖。問題來了?會死鎖麼?
    我們知道同一執行緒如果重複申請同一個互斥鎖那麼必然會死鎖?這裡問題轉換到訊號處理函式跟之前的執行緒A會是同一個執行緒上下文麼(即是同一個執行緒麼)?我們試驗一下。實驗之前需要明確幾點:
    1.根據APUE 12.8,程序的處理函式與處理方式是程序中所有執行緒共享的。
    2.根據APUE 12.8,如果程序接收到訊號,該訊號只會被遞送到某一個單獨執行緒。一般情況下由那個執行緒引起訊號則遞送到那個執行緒。如果沒有執行緒引發訊號,訊號被髮送到任意執行緒。



     上面程式首先共享了一個共同的SIGUSR1訊號處理函式,主控執行緒A然後產生一個執行緒B,執行緒B首先獲得全域性互斥鎖,然後執行一個長5秒的程式,然後釋放鎖。在B運行了大概2秒的時候,執行緒A給本程序(注意是程序,而不是某執行緒)傳送一個SIGUSR1訊號。此時,會死鎖麼?編譯執行看結果.

    連續運行了5次,都沒有死鎖。我們分析一下,當程序接收訊號時,程序把訊號並沒有遞送給執行緒B(因為沒有產生死鎖),也就是說是不是這個遞送過程被優化了?還是我們真的運氣好?需要進一步探查。接下來我們指定把訊號遞送給執行緒B,看會不會死鎖。

    接下來編譯執行:

    不出意料,果然死鎖了。
    也就是說,關於執行緒與訊號處理函式獲得同一把互斥鎖的問題,關鍵是看訊號被遞送給了那個執行緒,如果訊號是被遞送給了獲得鎖的那個執行緒,就會死鎖,如果不是之前獲得鎖的執行緒,程式就繼續執行。