在陳碩大大的文章提到,條件變量不丟消息的規範:
條件變量只有一種正確使用的方式,幾乎不可能用錯。對於 wait 端:
1. 必須與 mutex 一起使用,該布爾表達式的讀寫需受此 mutex 保護。
2. 在 mutex 已上鎖的時候才能調用 wait()。
3. 把判斷布爾條件和 wait() 放到 while 循環中。
對於 signal/broadcast 端:
1. 不一定要在 mutex 已上鎖的情況下調用 signal (理論上)。
2. 在 signal 之前一般要修改布爾表達式。
3. 修改布爾表達式通常要用 mutex 保護(至少用作 full memory barrier)。
4. 注意區分 signal 與 broadcast:“broadcast 通常用於表明狀態變化,signal 通常用於表示資源可用。(broadcast should generally be used to indicate state change rather than resource availability。)”
文章鏈接:http://www.cppblog.com/Solstice/archive/2013/09/09/203094.html
條件變量看過兩種比較常見的寫法
第一種 (UNIX編程寫法)
wait端: notify端
lock() lock()
while(!ready) ready=true
wait() dosomething
dosomething unlock()
unlock() notify()
第二種
wait端: notify端
lock() lock()
while(!ready) ready=true
wait() dosomething
dosomething notify()
unlock() unlock()
區別在於unlock後notify還是unlock前notity
其實之前一直不能理解這兩種變量絕對不會丟消息的說法,在我的理解下,
第一種在wait端還沒有獲取到鎖的時候,或者獲取到鎖後進入wait()之前,此時Nofity就會丟消息
第二種在wait端沒獲取到鎖的時候,此時notify就會丟消息
但是我覺得這裏還有個條件,是ready變量,雖然丟了條件變量的消息,但是隻要循環判斷ready變量,就不會錯過要通知的事件,這裏的鎖保護了ready變量不會被其他線程修改,同時也提供了內存屏障的作用!