儘管信號量還有其他用途,但它適用於生產者 - 消費者模型。您的程序邏輯負責確保爲等待次數提供適當的帖子數量。如果你發佈一個信號而沒有人等待,那麼當他們等待時,他們立即繼續。如果您的問題可以用信號量的計數值來解釋,那麼使用信號量應該很容易解決。
條件變量在某些方面有點寬容。例如,您可以使用cond_broadcast喚醒所有服務員,而製片人不知道有多少人。如果你沒有人在等待它,cond_signal condvar然後沒有反應。如果你不知道是否有興趣的聽衆,這很好。這也是爲什麼聆聽者應該總是在等待之前檢查互斥狀態 - 如果他們不這樣,他們就會錯過一個信號,直到下一個(可能永遠不會)醒來。
所以一個條件變量適用於通知感興趣的各方狀態已經改變:你獲得互斥量,改變狀態,信號(或廣播)condvar並釋放互斥量。如果這描述你的問題,你在condvar領土。如果不同的聽衆對不同的狀態感興趣,你可以直接播放,然後每個人都會醒來,找出他們是否已經找到了他們想要的狀態,如果不再等待。
用互斥量和信號量來嘗試這種事情確實非常困難。問題出現在你想要獲取互斥鎖時,檢查一些狀態,然後等待信號量發生變化。除非你可以自動釋放互斥量並等待信號量(在pthread中你不能),否則最終等待信號量同時持有互斥量。這會阻止互斥體,這意味着其他人無法將其用於執行您關心的更改。所以你會被誘惑添加另一個互斥體,這取決於你的具體要求。也許是另一個信號量。結果通常是不正確的代碼,有害的競態條件。
條件變量可以避免這個問題,因爲調用cond_wait會自動釋放互斥鎖,釋放它以供其他人使用。在cond_wait返回之前,互斥體會重新獲得。
IIRC有可能僅使用信號量來實現一種condvar,但是如果您要實現與condvar一起使用的互斥鎖需要使用trylock,那麼它是一個嚴重的頭部劃傷,並且定時等待。不建議。所以不要認爲你可以用condvar做什麼都可以用信號量來完成。此外,當然互斥體可以有很好的信號量缺乏行爲,主要是避免優先級倒置。
我剛剛意識到「正確初始化旗語」是不明確的。信號量是否設置爲1或0?我會說它應該被設置爲0.然後,信號量是否保護凸輪 - >狀態? – Blaisorblade 2014-06-01 22:45:33
在其他答案中提到的第二個片段中,當互斥體未被釋放時,您的線程將被阻塞。所以你的`sem_wait`方法永遠不會返回,因爲沒有其他線程可以獲得互斥體並調用`sem_signal`。但是,如果我在`sem_wait`之前釋放互斥並在等待之後再次請求它,我不會發生什麼。我知道這些步驟不是原子的,那麼會發生什麼? – sevenkplus 2016-10-03 15:31:54