第二章 程序管理(4)
管程機制
1.管程的組成
名為monitor_name的管程
Type monitor_name= monitor
variable declarations;
procedure entry P1(){…}
procedure entry P2(){…}
procedure entry Pn(){…}
initialization code;
2.管程的特點
任何程序只能通過呼叫管程提供的過程入口才能進入管程訪問共享資料;
就如同使用臨界資源,就要先通過其訊號量的申請。
任何時刻,僅允許一個程序在管程中執行某個內部過程。
管程如何實現同步
對共享變數互斥操作:
管程的特點直接實現了該要求,程序一次一個進入管程呼叫內部過程操作共享變數。
管程的互斥訪問完全由編譯程式在編譯時自動添上,無須程式設計師關心,能保證正確。
操作的同步控制:
靠條件變數的操作管理實現。
進入管程但不能獲取資源操作的過程將阻塞,並在滿足條件時被喚醒執行。
type p_c=monitor var in,out,count: interger; buffer: array[0,…,n-1] of item x,y: condition; 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; }
生產者-消費者問題的管程解決方法
Producer:
begin
repeat
生產an item in nextp;
p_c.put(nextp);
until
end
consumer:
begin
repeat
p_c.get(nextc);
消費an item in nextc;
until
end
3.條件變數
區域性於管程的變數有兩種:
普通變數
條件變數(用於控制程序阻塞和喚醒)
類似訊號量變數,但不取具體值;相當於每個阻塞佇列的佇列指標。
對條件變數的操作需結合對普通變數的條件判斷,從而控制程序狀態。
4.管程的優點
保證程序互斥地訪問共享變數,並方便地阻塞和喚醒程序。
管程可以以函式庫的形式實現。相比之下,管程比訊號量好控制。
管程可增強模組的獨立性:
系統按資源管理的觀點分解成若干模組,用資料表示抽象系統資源,使同步操作相對集中,從而增加了模組的相對獨立性
引入管程可提高程式碼的可讀性,便於修改和維護,正確性易於保證:
採用集中式同步機制。一個作業系統或併發程式由若干個這樣的模組所構成,一個模組通常較短,模組之間關係清晰。
5.管程的缺點:
大多數常用的程式語言中沒有實現管程,如果某種語言本身不支援管程,那麼加入管程是很困難的。
雖然大多數程式語言也沒有實現訊號量,但可將P、V操作作為一個獨立的子例程或作業系統的管理程式呼叫加入。
程序通訊
程序通訊是指程序之間的資訊交換
一、低階通訊——程序之間的互斥和同步
訊號量機制是有效的同步工具,但作為通訊工具缺點如下:
(1)效率低(通訊量少)
(2)通訊對使用者不透明(程式設計師實現,作業系統只提供共享儲存器供程式碼操作)
二、高階程序通訊
使用者直接利用作業系統提供的一組通訊命令,高效地傳送大量資料的通訊方式。
作業系統隱藏了程序通訊的細節,對使用者透明,減少了通訊程式編制上的複雜性。
1.程序通訊的型別
①共享儲存器系統(操作儲存區方式)
相互通訊的程序共享某些資料結構或共享儲存區,程序之間能夠通過這些空間進行通訊。
a.基於共享資料結構的通訊方式(低階)
程式設計師:提供對公用資料結構的設定及對程序間同步的處理。
作業系統:提供共享儲存器。
特點:複雜、低效率,還只適合傳遞相對少量的資料。
b.基於共享儲存區的通訊方式(高階)
在儲存器中劃出了一塊共享儲存區,諸程序可通過對共享儲存區中資料的讀或寫來實現通訊。
程序通訊前先向系統申請獲得共享儲存區中的一個分割槽,並指定該分割槽的關鍵字;
若系統已經分給了其他程序,則將該分割槽的描述符返回給申請者,申請者把獲得的共享儲存分割槽連線到本程序上;此後,便可像讀、寫普通儲存器一樣地讀、寫該公用儲存分割槽。多程序藉助該區通訊。
②訊息傳遞系統
最廣泛使用的一種,程序間的資料交換,以格式化的訊息為單位。遮蔽底層複雜操作。
單機:作業系統底層程式設計中的訊息傳遞系統呼叫;
計算機網路:訊息稱為報文。程式設計師直接利用系統提供的一組通訊命令(原語)進行通訊。(④客戶機-伺服器系統)
③管道通訊
所謂“管道”,是指用於連線一讀程序和一寫程序以實現通訊的一個共享檔案,又名pipe檔案。
向共享檔案輸入的寫程序以字元流形式將大量的資料送入管道;而接收管道輸出的讀程序則從管道中接收(讀)資料。
④Client-Server system
套接字(Socket)
遠端過程呼叫(遠端方法呼叫)
RPC應用開發步驟
1>定義客戶端、伺服器端的通訊協議(定義服務過程的名稱、呼叫引數的資料型別、返回引數的資料型別、底層傳輸型別(UDP/TCP)等。
2>開發客戶端程式。
3>開發伺服器端程式。
2.訊息傳遞通訊的實現方法
1)直接通訊方式
傳送程序利用OS所提供的傳送命令(原語),直接把訊息傳送給目標程序。此時,傳送程序和接收程序都以顯式方式提供對方的識別符號。通常利用系統通訊命令(原語):
Send(Receiver, message);
Receive(Sender, message);
利用直接通訊原語解決生產者——消費者問題
Producer:
repeat
…
produce an item in nextp;
…
send(consumer, nextp);
until false;
Consumer:
repeat
receive(producer, nextc);
…
consume the item in nextc;
until false;
2)間接通訊方式
基於共享資料結構的實體用來暫存傳送給目標程序的訊息;接收程序則從該實體中,取出對方傳送給自己的訊息。通常把這種實體稱為信箱。
訊息在信箱中可以安全地儲存,只允許核準的目標使用者隨時讀取。既可實時通訊,又可非實時通訊。
2)信箱訊息的傳送和接收
程序之間利用信箱進行通訊時,必須使用共享信箱。
Send(mailbox, message);
Receive(mailbox, message);
3.訊息傳遞系統的實現
單機和網路環境下的高階程序通訊廣泛採用“訊息傳遞”方式,需要考慮的問題:
①通訊鏈路的建立
計算機網路環境下,用原語顯式建立/拆除鏈路
單機系統只須利用系統原語,程序間鏈路由系統自動管理。
②訊息格式
單機系統,傳送與接收程序在同一臺機器,環境相同故格式簡單;
網路環境下,受不同目標機器的環境和長距離資訊傳輸等因素的影響,訊息格式較複雜,訊息常是“大頭+正文”
③同步方式
傳送程序阻塞、接收程序阻塞(無緩衝緊密同步)
傳送程序不阻塞、接收程序阻塞(伺服器程式)
傳送程序和接收程序均不阻塞(緩衝佇列)
4.訊息緩衝佇列通訊機制
①不需管理鏈路
②定義簡單資料結構(亦即訊息格式)
③實現傳送和接收的操作原語
資料結構
本機通訊訊息結構簡單,如下:
type message buffer = record
sender; 傳送者程序識別符號
size; 訊息長度
text; 訊息正文
next; 指向下一訊息緩衝區的指標
end
PCB中需要記錄有關通訊的資訊項
type ProcessControlBlock =record
…
mq; 訊息佇列隊首指標
mutex; 訊息佇列互斥訊號量
sm; 訊息佇列資源訊號量
…
end
原語程式碼:
傳送原語:
procedure send(receiver, a)
begin
getbuf(a.size, i); 根據a.size申請緩衝區
i.sender :=a.sender; 將傳送區a中的資訊複製到 i
i.size :=a.size;
i.text :=a.text;
i.next :=0;
獲取接收程序內部識別符號:
getid(PCB set, receiver, j);
wait(j.mutex);
insert(j.mq, i); 將訊息緩衝區插入目標訊息佇列
signal(j.mutex);
signal(j.sm);
end
接收原語:
procedure receive(b)
begin
j:=internal name; j為接收程序內部識別符號
wait(j.sm);
wait(j.mutex);
remove(j.mq, i); 將訊息佇列中的第i個訊息移出
signal(j.mutex);
b.sender :=i.sender;
b.size :=i.size; 將訊息緩衝區i中的資訊
b.text :=i.text; 複製到接收區b
end
執行緒
1.執行緒的引入
多道程式管理:追求效率的目的下實現“併發”
多執行緒系統中,同一個程序中的多個執行緒
共享程序資源
可併發執行
2.執行緒的屬性
輕型實體:只需一點必不可少的、能保證獨立執行的資源。(TCB)
獨立排程和分派的基本單位:排程切換迅速且開銷小。
可併發執行
共享程序資源:同進程中的執行緒可共享相同的程序地址空間、已開啟檔案、訊號量機構等。
3.執行緒的資訊
狀態引數
識別符號、執行狀態、優先順序、暫存器狀態、堆疊、專有儲存器、訊號遮蔽等。
執行狀態
執行、就緒、阻塞
4.執行緒的建立和終止
建立新執行緒
利用執行緒建立函式(或系統呼叫),提供相應引數。執行緒建立函式執行完後,返回一個執行緒識別符號供以後使用。
執行緒被終止
不立即釋放資源,只有當程序中的其它執行緒執行分離函式後,資源才分離出來能被其它執行緒利用。
被終止而未釋放資源的執行緒仍可被需要它的執行緒呼叫,使其重新恢復執行。
多執行緒變成舉例
netgameserver.java
public class netgameserver //主類
{ static int usercount=1;
public static void main(String args[])//main函式
{Socket client=null; ...
new Serthread(client).start();}//啟動新執行緒 …}
}
class Serthread extends Thread //自定義的執行緒類
{ String url="jdbc:odbc:userInfo";
Connection con; Statement stmt;
Socket thclient;
DataInputStream in=null;
…
public void run()//執行緒執行run函式----->
{System.out.println("a server thread started !");
boolean userlistfirshow=false;
while(true)//開始監聽
{
if(!userlistfirshow)
……}
}
}
5.多執行緒系統中的程序
程序只是用於分配系統資源
包括多個執行緒
不是執行實體,執行緒在程序範圍內作為執行實體。
執行緒與程序的比較
排程:執行緒作為CPU排程的基本單位,而程序只作為其它資源分配單位。
併發性:程序之間可以併發,實質上是不同程序中的兩個執行緒併發。一個程序的多個執行緒之間亦可併發。
擁有資源:程序間資源相互獨立;同一程序的各執行緒間共享。某程序內的執行緒在其它程序不可見
系統開銷:執行緒上下文切換在同進程環境下上下文切換要快得多。因為同進程內執行緒間共享記憶體地址和開啟的檔案資源;
6.執行緒的管理
同步和通訊機制
(1)互斥鎖
比較簡單的,控制執行緒互斥訪問資源;
適用於高頻度使用的關鍵共享資料和程式段;
unlock和lock兩個鎖操作原語;
(2)條件變數
與互斥鎖一起使用
鎖保證互斥進入臨界區,但利用條件變數使執行緒阻塞
不滿足條件時,wait條件變數:
釋放互斥鎖
程序阻塞在條件變數指向佇列中
被喚醒後要重新再設互斥鎖
(3)訊號量
私用訊號量(private samephore)
用於同進程的執行緒間同步,資料結構存放在應用程式的地址空間。屬於特定程序,OS感知不到其存在。
公用訊號量(public samephore)
用於不同程序間或不同程序中執行緒的同步,資料結構由OS管理,存放在受保護的系統儲存區。
7.執行緒的實現方式
(1)核心執行緒KST
依賴於核心,利用系統呼叫由OS核心在核心空間完成建立、撤消、切換等執行緒工作。
優缺點:
優點:
1>多處理器系統下可實現多執行緒並行
2>一個執行緒發起系統呼叫而阻塞,不會影響其它執行緒的執行
3>執行緒切換開銷遠小於程序切換
4>核心本身也採用多執行緒技術可提高系統執行速度和效率
缺點:
使用者態執行執行緒,排程和管理執行緒則是核心態。模式的切換開銷大。
(2)使用者執行緒ULT
排程由應用軟體內部進行,通常採用非搶先式和更簡單的規則,也無需使用者態/核心態切換,速度比kst快。
優缺點:
優點:
1>使用者執行緒的維護由應用程序完成;核心不瞭解使用者執行緒的存在;執行緒切換不需要核心特權;
2>使用者執行緒排程演算法可針對應用優化;
3>多執行緒的實現與平臺無關
缺點:
1>一旦系統呼叫引起程序阻塞,則整個程序的所有執行緒都不能執行
2>以程序為單位分配cpu,所有在多處理器系統中沒有優勢
(3)組合方式:
核心支援多KST執行緒的管理,同時也允許使用者應用程式級的執行緒管理。