2009-07-09 34 views
8

隨着pthread_cond_t的,我們有一個互斥體相關聯,當信號的情況我見過這樣的代碼調用pthread_cond_broadcast與互斥舉行或不?

pthread_mutex_lock(&mutex); 

//code that makes condition true 

pthread_cond_broadcast(&cond); 
pthread_mutex_unlock(&mutex); 

pthread_mutex_lock(&mutex); 

//code that makes condition true 

pthread_mutex_unlock(&mutex); 
pthread_cond_broadcast(&cond); 

哪一個是正確的方法是什麼? (這有什麼關係嗎?)

回答

13

取決於接收器在做什麼(以及其他來源)。

在你的第二個代碼示例中,有可能在解鎖和廣播之間,會有一堆其他線程出現並執行某些組合,這些組合會使條件再次失效。你會毫無意義地播出。而且,當您更改條件時,您不一定會有同樣的服務員,這可能會影響您的設計。

一個像樣的水槽不應該在乎它是否被喚醒並且條件是錯誤的,特別是如果您使用廣播。只要條件的每一次變化都是「真」,最終都會跟隨一個廣播,我敢肯定,如果使用適當的接收器,您可以無論是否使用鎖,都可以廣播一個條件變量。

所以我不認爲它真的很重要,但我個人認爲,如果只是爲了避免擔心,我會在鎖定的情況下播放。 「原子改變和信號」可能會簡化白板上的狀態圖,而不是「稍後改變......信號」。

兩者都是正確的(不等待沒有互斥體,這是不允許的),但我不認爲這會是太難以拿出在第二種情況下可能出錯的用途,這將不會第一次出錯。不過,他們可能不得不讓一些服務員做一些不尋常的事情。規範相當隱祕地表示「如果需要可預測的調度行爲,那麼該線程應該被調用pthread_cond_broadcast()或pthread_cond_signal()的線程鎖定」。

http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_signal.html

+0

有同樣的問題,我找到了你的答案。我已經關注了你的鏈接,我認爲他引用的內容與前面的內容有關:「如果在一個條件變量上阻塞了多個線程,調度策略將確定線程被解除阻塞的順序。」 – wilx 2011-05-17 09:42:59

+0

@wilx:是的,我的擔心是「不可預知的調度行爲」所允許的。例如,假設您有一個已記錄的調度程序,或者有一個選項,互斥量和條件變量選擇線程以FIFO爲基礎進行喚醒。如果「pthread_cond_signal」的調用者未持有互斥鎖,那麼「隱含」句子是否意味着該行爲不會成爲FIFO?我會這麼認爲,但我不知道「可預測」的正式定義,所以我覺得它很神祕。除了在RT系統中,我總是把時間安排看作是不可預測的,但我不希望它變得怪異。 – 2011-05-17 09:48:06

+0

沒有已知的情況,無論您的廣播在解鎖之前還是解鎖後都很重要。如果您在解鎖後將信號移動到一個非常困難的位置,那麼可以構建破解代碼。 – 2011-08-28 12:48:43