多個執行緒在讀寫某個共享資料(全域性變數等)時必須通過某種方法實現共享資料的互斥訪問或者同步訪問(例如執行緒 b等待執行緒
a 的結果以繼續執行)。其中,訊號量是一種最常見的方法。
訊號量是一種約定機制:在共享資源的互斥訪問中,它約定當乙個執行緒獲得訊號量(wait
)後,其他執行緒不可以再次獲得該訊號量直到訊號量被釋放(
give);在同步機制中,它約定等待訊號量(
take
)的執行緒(或者說等待訊號更確切)在收到訊號量之前應該處於阻塞狀態,直到其他執行緒傳送該訊號量(post)。
通常情況,對訊號量只能實施三種操作:建立乙個訊號量(
create
)、等待訊號量(
wait)或者掛起(
pend
)、給訊號量(
give
)或者傳送(
post)。作業系統應該包含乙個等待訊號量執行緒佇列(用於存放等待訊號量的執行緒),當訊號量可以被獲得時,作業系統依據某種策略從佇列中選擇乙個可以獲得訊號量的執行緒以繼續執行。
sylixos 訊號量包括四種型別:二進位制訊號量、計數型訊號量、互斥訊號量(簡稱互斥量)和讀寫訊號量。相關訊號量介紹:
有十個執行緒(執行緒a、執行緒
1...
執行緒 9
)和乙個變數
v,執行緒
a 需要寫變數
v,執行緒
1... 執行緒 9
需要讀變數 v。
我們假設只有在變數
v 的值改變時,讀者執行緒才需要讀變數
v,在變數 v 的值不變時,讀者執行緒需要阻塞。
讀者執行緒阻塞前可能需要一種「判斷」操作,判斷變數 v 當前的值是否與上一次讀到的值不一致;「判斷」操作前需要加鎖,如果一致那麼讀者執行緒需要阻塞,真正進入阻塞狀態前讀者執行緒又需要釋放該鎖,釋放鎖與阻塞需要是乙個不可打斷的原子操作。
我們可以想象一下釋放鎖與阻塞不是乙個原子操作的情形,如果讀者執行緒在釋放鎖與阻塞之間被執行緒
a 搶占了,毫無疑問,執行緒
a 可以成功獲鎖,執行緒
a 寫變數
v,變數
v 的值改變了,但讀者執行緒卻阻塞了,顯然讀者執行緒丟失了一次對變數
v 值改變的響應!
a 寫變數
v 後以廣播的方式「通知」多個讀者執行緒去讀該變數。
我們需要一種新的執行緒間通訊手段——
條件變數來解決以上問題——
釋放鎖與阻塞是乙個原子操作
和能以廣播的方式「通知」多個讀者執行緒。
條件變數是多執行緒間的一種同步機制,條件變數與互斥鎖一起使用時,允許執行緒以無競爭的形式等待條件的發生。條件本身由互斥量保護,因此執行緒在改變條件之前必須首先鎖住互斥量,其他執行緒在獲得互斥量之前不會察覺到條件的改變。
執行緒同步 條件變數和訊號量
上一節提到了執行緒互斥和同步的概念,並且給出了兩種用於解決共享資源互斥的利器 互斥鎖和讀寫鎖。那麼本節將介紹兩種用於解決執行緒同步的概念 條件變數和訊號量。一.條件變數 1.基本概念 互斥鎖的缺點是它只有兩種狀態 鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補了互斥鎖...
多執行緒 互斥量 訊號量和條件變數
通常用於互斥訪問 pthread mutex t m mutex pthread mutex intit m mutex,null pthread mutex lock m mutex pthread mutex unlock m mutex pthread mutex destory m mute...
網路程式設計 條件變數和訊號量 鎖
條件變數和訊號量的區別 1 使用條件變數 broadcast 可以一次喚醒所有等待者,而這個訊號量沒有的功能,感覺是最大區別。應用場景 當程式退出要喚醒所有執行緒時,執行緒池的執行緒用條件變數 單一執行緒用訊號量 僅有互斥量的執行緒設定某個執行緒退出的標誌 2 訊號量是有乙個值 狀態的 而條件變數是...