主題1:多線程死鎖
putQ
setFlag
線程2:
while (1) {
waitFlag
processQ
clearFlag
}
這是一個面試問題。我不確定是否有線程1的while循環。 但是,答案就像當線程2重新進入while循環時,兩個線程進入死鎖。
誰能告訴我什麼是死鎖的條件?謝謝。
主題1:多線程死鎖
putQ
setFlag
線程2:
while (1) {
waitFlag
processQ
clearFlag
}
這是一個面試問題。我不確定是否有線程1的while循環。 但是,答案就像當線程2重新進入while循環時,兩個線程進入死鎖。
誰能告訴我什麼是死鎖的條件?謝謝。
我覺得OP的評論是正確的:
@Gray:這是最有可能不是一個死鎖,而是一個競爭條件。然而,該應用程序卡住不處理隊列,所以它是一個鎖。
@Wug:這可能是「小巫見大巫情況」裏,而thread 1
已經把在隊列中,更新標誌,thread 2
不會注意到。請參閱下面的操作步驟。
潛在的鎖的情況:
ProcessQ
元素0(處理前元件)PutQ
元件1SetFlag
ClearFlag
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
}
你的意思是說只有一個元素可以放在Q中? – babysnow
不,在給出的例子中,如果元素1是插入的最後一個元素,它將永遠不會被處理。 –
我看到的一個問題是線程1(T1
)在短時間內調用兩次代碼。這裏是一個可能的行動路線:
T2: waitFlag
T1: putQ
T1: setFlag
T2: processQ
T1: putQ
T1: setFlag
T2: clearFlag
如果T1
再也沒有放入任何東西,T2
永遠不會處理第二項。但這不是一個僵局。
假設圍繞第一個塊有一個循環,我相信這個例子試圖喚起人們對計算信號量的重要性的關注。示例中的「標誌」不計數,因此通過第一個循環的多次傳入會將多個項目放入隊列中,但標誌只能被「設置」一次,因此第二個循環只能觸發一次。一個信號量會在上層循環中爲每個V
計數一次,這樣第二個循環將根據需要運行多次,同時減少P
的計數。
我沒有看到它...除非它是微不足道的情況下線程1只運行一次,線程2將後永遠等待下去。 – Wug
你確定你的意思是「僵局」而不是「種族條件」嗎? – Gray
這可能是比賽條件,抱歉的混淆。 – babysnow