―、管程的提出
採用訊號量及p、v同步機制來編寫併發程式,對於共享變數及訊號量變數的操作將被 分散於各個程序中,其缺點如下。
(1)程式易讀性差,因為要了解對於一組共享變數及訊號量的操作是否正確,則必須通 讀整個系統或者併發程式。
(2)程式不利於修改和維護,因為程式的區域性性很差,所以任一組變數或一段**的修 改都可能影響全域性。
(3)正確性難以保證,因為作業系統或併發程式通常很大,要保證這樣乙個複雜的系統 沒有邏輯錯誤是很難的。
為了更易於編寫正確的程式,brinch hansen和hoare提出了一種高階同步機制,稱為管程(monitor)
二、管程的概念及組成
乙個管程是乙個由過程、變數及資料結構等組成的乙個集合,它們組成乙個特殊的模組或軟體包。程序可在任何需要的時候呼叫管程中的過程,但它們不能在管程之外宣告的過程 中直接訪問管程內的資料結構。
乙個管程由四個部分組成。它們是管程名稱、共享資料的說明、對資料進行操作的一組 過程和對共享資料賦初值的語句。管程能保障共享資源的互斥執行,即一次只能有乙個程序 可以在管程內活動。該效能是由管程本身實現的。因此,程式設計師可以不必顯式地編寫程式代 碼去實現這種同步制約。圖4-5給出管程的結構,它定義了一種共享資料結構。
圖4-6展示了用一種抽象的、類pascal語言描述的管程。這裡不能使用c語言,因為管 程是語言特性而c語言並不支援它。
管程具有三個主要的特性。
(1)模組化,乙個管程是乙個基本程式單位,可以單獨編譯。
(2)抽象資料型別,管程是一種特殊的資料型別,其中不僅有資料,而且有對資料進行 操作的**。
(3)資訊隱蔽,管程是半透明的,管程中的外部過程函式)實現了某些功能,管程中的 外部過程(函式)實現了某些功能,至於這些功能是怎樣實現的,在其外部則是不可見的。
管程中的共享變數在管程外部是不可見的,外部只能通過呼叫管程中所說明的外部過程 (函式)來間接地訪問管程中的共享變數;為了保證管程共享變數的資料完整性,規定管程互斥進人;管程通常是用來管理資源的,因而在管程中應當設有程序等待隊以及相應的等待 及喚醒操作。
管程有乙個很重要的特性,即任一時刻管程中只能有乙個活躍程序,這一特性使管程能有效地完成互斥。管程是程式語言的組成部分,編譯器知道它們的特殊性,因此可以採用與其他過程呼叫不同的方法來處理對管程的呼叫。典型的處理方法是,當乙個程序呼叫管程過程時,該過程中的前幾條指令將檢查在管程中是否有其他的活躍程序。如果有,呼叫程序將被掛起,直到另乙個程序離開管程將其喚醒。如果沒有活躍程序在使用管程,則該呼叫程序可以進人。進人管程時的互斥由編譯器負責,但通常的做法是用乙個互斥量或二元訊號量。 因為是由編譯器而非程式設計師來安排互斥,所以出錯的可能性要小得多。在任一時刻,編寫管 程的人無須關心編譯器是如何實現互斥的,他只需知道將所有的臨界區轉換成管程過程即 可,絕不會有兩個程序同時執行臨界區中的**。
三、管程中的條件變數
儘管管程提供了一種實現互斥的簡便途徑,但這還不夠。我們還需要一種辦法使得程序在無法繼續執行時被阻塞。
在生產者——消費者問題中,很容易將針對緩衝區滿和緩衝區空的測試放到管程過程中,但是生產者在發現緩衝區滿的時候如何阻塞呢?解決的方法是引入條件變數(condition variables)以及相關的兩個操作:wait和signal。當乙個管程過程發現 它無法繼續執行時(例如,生產者發現緩衝區滿),它會在某個條件變數上(如full)執行 wait操作。該操作導致呼叫程序自身阻塞,並且還將另乙個以前等在管程之外的程序調人管程。另乙個程序,比如消費者,可以喚醒正在睡眠的夥伴程序,這可以通過對其夥伴正在等待的乙個條件變數執行signal完成。
條件變數不是計數器,條件變數也不能像訊號量那樣積累訊號以便以後使用。所以,如果向乙個條件變數傳送訊號,但是在該條件變數上並沒有等待程序,則該訊號會永遠丟失。 換句話說,wait操作必須在signal之前。這條規則使得實現簡單了許多。實際上這不是乙個問題,因為在需要時,用變數很容易跟蹤每個程序的狀態。原本要執行signal的程序, 只要檢查這些變數便可以知道該操作是否有必要。
如果在管程**現多個程序時怎樣考慮?例如,當乙個進人管程的程序執行等待操作 時,它應當釋放管程的互斥權,當乙個進入管程的程序執行喚醒操作時(如p喚醒q),管 程中便存在兩個同時處於活動狀態的程序。處理方法有三種:
(1)p等待q繼續,直到q退出或等待;
(2)q等待p繼續,直到p等待或退出;
(3)規定喚醒為管程中最後乙個可執行的操作。
第一種方法是hoare提出的,因此稱為hoarc管程。在設計hoare管程時,由於管程是互斥進人的,所以當乙個程序試圖進人乙個已被占用的管程時它應當在管程的入口處等待, 因而在管程的入口處應當有乙個程序等待佇列,稱作入口等待佇列。如果程序p喚醒程序 q,則p等待q繼續,如果程序q在執行又喚醒程序r,則q等待r繼續,……,如此, 在管程內部,由於執行喚醒操作,可能會出現多個等待程序,因而還需要有乙個程序等待隊 列,這個等待佇列被稱為緊急等待佇列。它的優先順序應當高於人口等待佇列的優先順序signal (c):如果c鏈為空,則相當於空操作,執行此操作的程序繼續;否則喚醒第乙個等待者, 執行此操作的程序的pcb人緊急等待佇列的尾部。
第二種方法有一種實現稱為mesa管程;
第三種方法是hansen提出的,稱為brinch hansen 管程。
四、用管程解決生產者——消費者問題
下面給出了用類pascal語言管程實現的生產者——消費者問題的解法框架。使用類pascal 語言的優點在於清晰、簡單,並且嚴格符合 hoare/brinch hansen 模型。
monitor producerconsumer
condition full,empty;
integer count;
procedure insert(item:integer);
begin
if count == n then wait(full);
insert_item(item); count++;
if count == 1 then signal(empty);
end;
function remove: integer;
begin
if count == 0 then wait(empty);
remove = remove_item; count--;
if(count) == n - 1 then signal(full);
end;
count = 0;
end monitor;
procedure producer;
begin
while true dobegin
item = produce_item;
produceconsumer.insert(item);
end
end;
procedure_consumer;
begin
while true do
begin
item = producerconsumer.remove;
consume_item(item);
end;
end;
該解法框架中設計了乙個管程模組producerconsumer,其中定義了兩個條件變數full和 empty,並且提供了兩個操作insert和remove。生產者程序生產出產品後,呼叫管程pro_ ducerconsumer的insert操作完成將產品放人緩衝區的過程;而消費者則呼叫管程producer-consumer 的 remove 操作完成從緩衝區取產品 的過程。管程producerconsumer 的互斥問題由 類pascal編譯器解決,在程式設計時中無須考慮。
作業系統是什麼? 作業系統的基本概念
巨集觀上並行,微觀上時間片 併發 分時執行。系統資源可供記憶體中多個併發執行的程序共同使用。兩種資源共享方式 1 互斥共享方式 一段時間內只允許乙個程序訪問該資源。而把一段時間內只允許乙個程序訪問的資源稱為臨界資源或獨佔資源。2 同時訪問方式 一段時間內允許多個程序使用。巨集觀上同時,微觀上分時共享...
作業系統是什麼?Linux作業系統概述!
linux 也是眾多作業系統之一,要想知道 linux 是什麼,首先得說一說什麼是作業系統。硬體是計算機賴以工作的實體,包括顯示器 鍵盤 滑鼠 硬碟 cpu 主機板等 作業系統 operating system,os 是軟體的一部分,它是硬體基礎上的第一層軟體,是硬體和其它軟體溝通的橋梁 或者說介面...
作業系統是什麼? 讀作業系統概念第六版
作業系統是幾乎所有計算機系統的乙個重要組成部分。計算機系統可以 粗分為四個部分 硬體 作業系統 應用程式和使用者。計算機系統的基本目的是執行使用者程式並能更容易地解決使用者問題。為了實現這一目的,構造了計算機硬體。由於僅僅有硬體並不一定容易使用,因此開發了應用程式。這些應用程式需要一些共同操作,如控...