在前面 程序 中提到,有訊號量與互斥量之後,似乎程序間通訊就很容易了。但事實上並不然,pv操作不慎是很容易導致兩個程序都被阻塞的,這種情況就叫做死鎖(dead lock)。
為了更容易編寫出正確的程式,1973和2023年hansen與hoare提出了另一種高階同步原語,稱為管程(monitor)。
但他們提出的方式略微有些差別,不過核心都是資源集中管理,將系統中資源通過抽象的形式描述。
管程是乙個由過程、變數、資料結構等組成的集合,它們共同形成乙個模組或是軟體包。程序可以在任何需要的時候呼叫管程中的過程,但不能在管程宣告之外的過程中訪問管程內的資料結構。
還提供了一種條件結構(condition construct)的機制來保障多程序安全、有效的共享資料。如為實現程序互斥同步,可以定義一些條件變數,這些條件變數只能被wait
或者signal
操作訪問。前者表示呼叫該操作的程序將掛起,而後者是啟動乙個被掛起的程序,但與v操作不同的是後者不會改變條件變數的狀態,如果失敗則等於空操作。
假定要仍然用來解決生產者與消費者問題,則可以定義notfull, notempty
的條件變數,類語言過程如下:
type producer-consumer=monitor
var buffer : array[0,...,n-1] of item;
in, out, count : interger;
notfull, notempty : condition; //定義條件變數
procedure entry put(item) //將產品放入緩衝區
begin
if count >= n then notfull.wait; //緩衝區滿則等待
buffer(in):=nextp;
in:=(in+1) mod n;
count:=count+1;
if notempty.queue then notempty.signal; //喚醒等待者
endprocedure entry get(item)
begin
if count <= 0 then notempty.wait; //緩衝區空等待
nextc:=buffer(out);
out:=(out+1) mod n;
count:=count+1;
if notfull.queue then notfull.signal //喚醒生產者
endbegin in:=out:=0; count:=0; end //初始化
cobegin
producer : begin
repeat
produce an item in nextp;
producer-consumer.put(item);
until false;
endconsumer:begin
repeat
producer-consumer.get(item);
consume the item in nextc;
until false;
endcoend
其實管程概念實際上是一種將互斥或訊號包裝的做法,對管程的支援基本都由程式語言及編譯器實現,這樣一來就可以減少人為失誤導致的死鎖,也使的編寫大大簡便。 作業系統 管程
1.管程 英語 monitors,也稱為監視器 是一種程式結構,結構內的 多個子程式 物件或模組 形成的多個工作執行緒互斥訪問共享資源。這些共享資源一般是硬體裝置或一群變數。管程實現了在乙個時間點,最多只有乙個執行緒在執行管程的某個子程式。與那些通過修改資料結構實現互斥訪問的併發程式設計相比,管程實...
作業系統原理 管程
將共享變數及操作共享變數的所有方法封裝在乙個模組中。一組區域性變數 共享變數 操作區域性變數的一組方法 區域性變數的初始語句 任何程序只能通過管程提供的入口才能訪問共享資料 任何時刻只允許乙個程序訪問管程的某個方法 對共享變數的互斥操作 管程的特點決定了對共享資源的互斥操作,管程同一時刻只允許乙個程...
作業系統之管程
管程的出現是一種程序同步工具。管程的特性保持了程序互斥,無須程式設計師自己實現互斥,從而降低了死鎖發生的可能性。同時管程提供了條件變數,可以讓程式設計師靈活地實現程序同步。管程有點類似於在物件導向時候學習到的類。管程有四個部分組成 管程的名字 區域性於管程內部的共享結構資料說明 對該資料結構進行操作...