計算機作業系統——管程
一.什麼是管程
1.1973年,Hoare和Hanson提出管程思想:
將共享變數及對共享變數能夠進行的所有操作集中在一個模組中。
(把訊號量及其操作原語“封裝”在一個物件內部)
二.管程的組成
管程需要封裝 (1)一組區域性變數 (2)對區域性變數操作的一組過程(2)對區域性變數進行初始化的語句。
三.管程的特點
1.任何程序只能通過呼叫管程提供的過程入口才能進入管程訪問共享資料;
就如同使用臨界資源,就要先通過其訊號量的申請。
2.任何時刻,僅允許一個程序在管程中執行某個內部過程。
四.管程的同步控制(條件變數)
1.普通變數
2.條件變數(用於控制程序阻塞和喚醒)
類似訊號量變數,但不取具體值;相當於每個阻塞佇列的佇列指標。
對條件變數的操作需結合對普通變數的條件判斷,從而控制程序狀態。
3.關於條件變數的操作
x.wait將執行程序掛到x對應的等待佇列上;
x.signal喚醒x相應的等待佇列上的一個程序。
(signal操作,是重新啟動一個被阻塞的程序,但如果沒有程序被阻塞,則不產生任何效果 而訊號量機制中的signal操作,若沒有需要喚醒的程序,必須要做的還有修改訊號量變數的值。)
五.管程的優缺點
優點:
(1)保證程序互斥地訪問共享變數,並方便地阻塞和喚醒程序。管程可以以函式庫的形式實現。相比之下,管程比訊號量好控制。
(2)管程可增強模組的獨立性:系統按資源管理的觀點分解成若干模組,用資料表示抽象系統資源,使同步操作相對集中,從而增加了模組的相對獨立性
(3)引入管程可提高程式碼的可讀性,便於修改和維護,正確性易於保證:採用集中式同步機制。一個作業系統或併發程式由若干個這樣的模組所構成,一個模組通常較短,模組之間關係清晰。
缺點:
大多數常用的程式語言中沒有實現管程,如果某種語言本身不支援管程,那麼加入管程是很困難的。 雖然大多數程式語言也沒有實現訊號量,但可將P、V操作作為一個獨立的子例程或作業系統的管理程式呼叫加入。
六.生產者-消費者問題管程示例
type p_c=monitor
var in,out,count: interger;
buffer: array[0,…,n-1] of item
x,y: condition; //x:代表沒有空這種條件 y:代表沒有產品這種條件
procedure entry put(var product:item) //生產者函式
{ if count>=n then x.wait; //程序間的同步靠條件變數的操作實現
buffer[in]=product;
in=in+1 mod n;
count=count+1;
y.signal;
}
procedure entry get(var product:item) //消費者函式
{ if count<=0 then y.wait;
nextc=buffer[out];
out=out-1 mod n;
count=count-1;
x.signal;
}
{ in=out=0;
count=0;
}