訊號量同步互斥問題
阿新 • • 發佈:2019-02-03
一、訊號量
訊號量是一種抽象資料型別
- 由一個整型(sem)變數和兩個原子操作組成
- P():sem減1,如果sem<0進入等待狀態,否則繼續
- V():sem加1,如果sem<=0則喚醒一個等待的執行緒
二、管程
管程是一種用於多執行緒互斥訪問共享資源的程式結構
- 區域性資料變數只能被管程的過程訪問,任何外部過程都不能訪問
- 一個程序通過呼叫管程的一個過程進入管程
- 在任何時候,只能有一個程序在管程中執行,呼叫管程的任何其他程序都被阻塞,以等待管程可用
管程的使用
- 管理共享資料
- 定義訪問共享資料的方法
條件變數
- 條件變數是管程內的等待機制
1.1. 進入管程的執行緒因資源被佔用而進入等待狀態
1.2. 每個條件變量表示一種等待原因,對應一個等待佇列 - Wait()操作
2.1. 將自己阻塞在等待佇列中
2.2. 放棄對管程的互斥訪問許可權(同一時刻管程只能有一個程序訪問) - Signal()操作
3.1. 將等待佇列中的一個執行緒喚醒(訊號量機制中的Signal是釋放一個訊號量,如果訊號量≤0則喚醒一個執行緒)
三、生產者消費者問題
①生產者在生成資料後放在一個緩衝區裡
②消費者從緩衝區中讀取資料
③任何時刻只能有一個生產者或消費者可以訪問緩衝區
問題分析:
①任何時刻只能有一個執行緒操作緩衝區
②緩衝區滿時,生產者要等待消費者
③緩衝區空時,消費者要等待生產者
利用訊號量解決
利用管程解決
四、哲學家就餐問題
問題描述
解決方案
五、讀者-寫者問題
管程的狀態變數
- AR:正在讀的讀者數量
- AW:正在寫的寫者數量
- WR:等待讀的讀者數量
- WW:等待寫的寫者數量
- okToRead:讀者的等待佇列
- okToWrite:寫者的等待佇列
讀者模組(寫者優先)
startRead():如果有寫者正在寫或等待寫,則進入等待佇列
DoneRead():如果沒有讀者在讀且有寫者等待寫,則喚醒寫者
寫者模組(寫者優先)
StartWrite():如果有讀者在讀或有寫者在寫,則進入等待佇列
DoneWrite():如果有寫者等待寫,則優先喚醒寫者,或者喚醒等待的讀者