2011-08-29 38 views
3

有點混亂!如果我們看看下面的場景,會出現什麼問題:我的目標是瞭解條件變量與互斥鎖的混合。條件隨着互斥體變化

T1

  1. LOCK {MUTEX}
  2. CHECK VARIABLE
  3. 如果未設置,WAIT ON條件變量
  4. UNLOCK {MUTEX}轉到1

T2

  1. 修改變量;
  2. 信號條件變量

可能有步驟2和3之間的競爭條件,因此我們使用互斥體。我不明白的是cond var + mutex的基本思想。

+0

你想在這裏做什麼行爲?我可以解釋這段代碼是如何構造的,但我不明白它是如何做到有用的。 T1是否突破該循環?是否正在等待T2修改變量? – Erik

+1

在修改變量之前,T2不應該鎖定互斥? – sizzle

+0

會導致死鎖,因爲T1在等待條件變量時保持鎖定狀態發信號爲 – Erik

回答

1

有兩個問題與寫入結束省略鎖:

  1. 如果你想修改變量不能寫入原子(即,它是大於int - 雖然細節取決於你正在使用的CPU架構!),你需要一個鎖來確保你沒有「剪切」。這是當變量在中途寫入時發生讀取的時候。例如,您可以將0xAAAAAAAABBBBBBBB寫入先前爲0的64位變量,而另一個線程可能只會看到0xAAAAAAAA00000000或0x00000000BBBBBBBB。該鎖可防止讀者看到進行中的寫入,從而避免此問題。
  2. 讀者可能會看到您的變量處於仍然需要等待的狀態,然後在可以進入睡眠之前,作者可以更新變量併發送條件變量。因此,你的線程永遠睡覺。在寫入側取鎖可防止發生這種情況。

還要注意,條件變量的許多用途不僅僅是修改鎖中的一個標誌 - 例如它們可能會操縱鏈表或其他複雜的數據結構。在這種情況下,需要鎖來保護該數據結構以及條件變量。

+3

還有一個更重要的原因:沒有鎖定,T2可以在T1執行步驟2和3之間執行步驟1和步驟2,然後T1將永久等待。 – caf

1

我要帶你的背景,你想要的行爲一些猜測,但我認爲你想要的東西看起來像這樣:

T1:
1.鎖互斥
2.檢查參數
3.解鎖互斥
4.等待條件變量
5.轉到1

T2:
1.鎖互斥
2.修改變量
3.解鎖互斥
4.信號條件變量

的互斥體是保護訪問的變量,讓你不會有不同的線程讀取,並在同一時間寫這一切都。

條件變量用於同步線程,以便您可以控制事件發生的順序。

+0

好吧。這正是我使用互斥鎖和條件變量的原因。 – sizzle

+0

@Erick,True,Mutex用於保護序列化變量訪問。但爲什麼cond_wait()需要解鎖相同的互斥鎖並等待,然後在等待後鎖定? – Whoami

+1

@ user916439條件變量等待您,與互斥鎖無關。解鎖互斥鎖允許其他線程在發出喚醒條件之前更新資源(鎖定,修改,解鎖)。當條件被喚醒時,互斥鎖被自動重新鎖定。它在內部完成,因爲POSIX指定了一個非常具體的原子行爲。您可以保證您擁有成功的pthread_cond_wait()上的資源。 –

0

你做錯了。條件變量具有與它們相關的互斥鎖。您需要先鎖定互斥鎖,然後再更改變量並將其釋放。

沒有死鎖 - pthread_cond_wait完全獲取關聯的互斥鎖作爲參數,因爲它可以解鎖互斥體時的互斥體(當您在等待條件變量的等待隊列中時釋放互斥體,這樣當條件變量發出信號時,你將感覺到被喚醒。