宋寶華: Linux死鎖的成因和常規調試方法(預告片)

  • 2019 年 11 月 23 日
  • 筆記

有一次給一群碼農演講,我噴口水噴了快一個小時,說spinlock等的正確使用以及死鎖的原因。下面有個人突然問,「老師,請問什麼叫死鎖?」。

我心裡想,把這個人拉出去槍斃一萬次 🙂 ,你這樣是怎麼做了幾年碼農的?這樣民族自強的機會在哪裡?但是我還是耐心地跟他解答了。我跟他說:「死鎖就是我們兩約好一起去跳樓,然後我們都跑到了頂層88樓的天台,然後我跟你說一句,'you jump, I jump',你也跟我說一句'you jump, I jump',最後你特馬也沒jump,我特馬也沒jump,所以跳樓這個壯舉就算是因為死鎖而永久地搞不下去了。」然後我問他明白了沒有,他說:「沒聽懂」。這個時候我狠不得把自己拉出去槍斃一萬次……

以上段子來源於真實事件,如有雷同,純屬巧合。哈哈哈哈。

言歸正傳,我們來看看死鎖的幾種形成原因。我認為起碼有三種:

1.自己掉坑裡了,這種我姑且簡稱自殺型。行動特徵:

有人說,死鎖不是兩個人的事情嗎?一個人也能自己把自己玩死?真的是可以的。最簡單的自殺型就是在10號中斷服務程式裡面調用irq_disable(10),因為irq_disable()會執行一個同步,等正在執行的10號中斷服務程式執行完,才繼續disable 10號中斷的動作。在10號中斷服務程式裡面調用irq_disable(10),等於在自己裡面等自己結束,而自己結束又必須irq_disable(10)返回。

2.A等B做完某事才能繼續,B也等A做完某事才能繼續;這種我姑且稱為互殺型。行動特徵:

3.A等B做完某事才能繼續,B等C做完某事才能繼續,C等A做完某事才能繼續;這種我姑且稱為群毆型。行動特徵:

互殺型應該是最簡單也最容易理解的,我們先從互殺型開始。下面的程式碼演示中2個執行緒child1和child2,展示了最簡單的互殺模型: