2012-10-03 220 views
1

主題1:多線程死鎖

putQ 
setFlag 

線程2:

while (1) { 
waitFlag 
processQ 
clearFlag 
} 

這是一個面試問題。我不確定是否有線程1的while循環。 但是,答案就像當線程2重新進入while循環時,兩個線程進入死鎖。

誰能告訴我什麼是死鎖的條件?謝謝。

+0

我沒有看到它...除非它是微不足道的情況下線程1只運行一次,線程2將後永遠等待下去。 – Wug

+0

你確定你的意思是「僵局」而不是「種族條件」嗎? – Gray

+0

這可能是比賽條件,抱歉的混淆。 – babysnow

回答

0

我覺得OP的評論是正確的:

  1. @Gray:這是最有可能不是一個死鎖,而是一個競爭條件。然而,該應用程序卡住不處理隊列,所以它是一個鎖。

  2. @Wug:這可能是「小巫見大巫情況」裏,而thread 1已經把在隊列中,更新標誌,thread 2不會注意到。請參閱下面的操作步驟。

潛在的鎖的情況:

  • T2:ProcessQ元素0(處理前元件)
  • T1:PutQ元件1
  • T1:SetFlag
  • T2:ClearFlag
  • T2:waitFlag

元素1可能永遠不會被處理。

編輯:

當然,下一個問題是:how do you fix that?

答案會是一個Conditional Variable(見pthread_cond_init和其他詳細信息):

主題1:

PutQ 
LockMutex 
SetFlag 
CondSignal 
UnlockMutex 

線程2:

while (1) { 
    LockMutex 
    while (FlagIsUnset) 
     CondWait 
    FlagUnset 
    UnlockMutex 
    ProcessQ 
} 
+0

你的意思是說只有一個元素可以放在Q中? – babysnow

+0

不,在給出的例子中,如果元素1是插入的最後一個元素,它將永遠不會被處理。 –

0

我看到的一個問題是線程1(T1)在短時間內調用兩次代碼。這裏是一個可能的行動路線:

  • T2: waitFlag
  • T1: putQ
  • T1: setFlag
  • T2: processQ
  • T1: putQ
  • T1: setFlag
  • T2: clearFlag

如果T1再也沒有放入任何東西,T2永遠不會處理第二項。但這不是一個僵局。

0

假設圍繞第一個塊有一個循環,我相信這個例子試圖喚起人們對計算信號量的重要性的關注。示例中的「標誌」不計數,因此通過第一個循環的多次傳入會將多個項目放入隊列中,但標誌只能被「設置」一次,因此第二個循環只能觸發一次。一個信號量會在上層循環中爲每個V計數一次,這樣第二個循環將根據需要運行多次,同時減少P的計數。