1. 程式人生 > >程序控制與同步

程序控制與同步

程序控制

程序控制的基本過程:
*程序的建立
*程序的終止
*程序的阻塞與喚醒
*程序的掛起和啟用

關於程序的親屬關係

系統中執行的程序並不都是孤立的,有的程序執行後,會呼叫其他程序來執行,
這樣就組成了程序間的父子關係。

可用 “程序圖”描述一個程序的家族關係,該圖實際就是一種有向樹。
程序樹示例

  • 感受程序及程序樹

1.“執行”——輸入“cmd”,啟動命令列控制檯
2.在cmd視窗輸入“notepad”啟動記事本。
3.現在程序“cmd.exe”和程序“notepad.exe”就組成了一個程序樹,後者為子程序,前者為父程序。
4.用“工作管理員”在“程序”頁,右擊cmd.exe選擇“結束程序樹”。則記事本子程序也會結束。

注:一些木馬服務端程式執行後會同時生成兩個木馬程序,這兩個程序互相監控、互相保護。對此類木馬,我們就可以分別對兩個木馬程序嘗試使用“結束程序樹”命令。

程序間的父子關係關係著資源的繼承。建立和撤銷程序時,其父、子程序要相應的被影響。

1.程序的建立
1)一個程序建立另一程序的事件(原因)

*使用者登入:分時情況下使用者的請求
*作業排程:批處理中
*提供服務:執行中的使用者程式提出功能請求,要建立服務程序(如列印服務)
*應用請求:應用程式自己建立程序,完成特定功能的新程序。(木馬程式)

2)建立過程

(1) 申請空白PCB
(2) 為新程序分配資源
主要是記憶體資源的處理
(3) 初始化程序控制塊
識別符號(包括父程序的)、程式計數器指向程式入口地址,就緒態、優先順序等資訊的填寫。
(4) 將新程序插入就緒佇列

原語是由若干指令構成的原子操作過程,作為整體實現功能,不可被打斷。

*OS通過呼叫程序建立原語Creat()建立新程序。

*其他各控制工作也都是由OS核心以“原語”的方式實現,以保證不被打斷。

2.程序的終止
1)引起程序終止的事件

*正常結束

*異常結束
記憶體越界錯誤
保護錯(許可權錯,如修改只讀檔案等)
非法指令(不存在的指令,程式異常轉向而把資料當指令)
特權指令錯(使用者態程式試圖執行只有OS可執行的指令)
執行超時、運算錯、i/o故障等

*外界干預
操作員或作業系統干預(死鎖時,可人為結束)
父程序請求終止子程序
父程序終止,子孫程序也跟著終止

2)終止過程
對上述事件,OS呼叫核心終止原語,執行下列過程:
(1) 根據程序標示符,檢索出該程序PCB,讀其狀態。
*IF 執行態,立即終止該程序,置排程標誌為真,指示重新進行排程。
*IF 有子孫程序,亦應予以終止,以防成為不可控程序。
(2) 歸還全部資源至其父程序或系統。
(3) 將該程序PCB從所在佇列或連結串列中移出。

3.程序的阻塞與喚醒
1)引起程序阻塞和喚醒的事件

*請求系統服務的滿足情況
*啟動某種需等待(I/O)操作
*合作需要的新資料尚未到達
*執行某功能的程序暫時無新工作可做(如傳送資料程序)

2)阻塞和喚醒過程
由程序呼叫阻塞原語阻塞自己,是主動行為:
(1)將PCB中的狀態改為阻塞
(2)該PCB加入到阻塞佇列中
(3)轉程序排程,將處理機分配給另一程序
(4)進行程序切換,即根據兩切換程序的PCB,保護與重新設定處理機狀態。

阻塞與喚醒原語作用相反,成對使用

阻塞程序等待的事件發生時,有關程序(如放棄該資源的程序)呼叫喚醒原語把等待該事件的程序喚醒。
(1)把阻塞程序從等待該事件的阻塞佇列中移出
(2)將其PCB中的現行狀態改為就緒
(3)將PCB插入到就緒佇列中。

4.程序的掛起與啟用

掛起原語將指定程序或阻塞程序掛起。
(1)檢查被掛起程序的狀態,活動就緒則改為靜止就緒,活動阻塞則改為靜止阻塞
(2)將該PCB複製到記憶體(方便檢查)/外存(對換)指定區域
(3)*若掛起的程序是執行態,則需重新進行程序排程。
注意:程序只能掛起自己或其子孫程序。

啟用原語的執行過程
若掛起程序在外存上,將其調入記憶體
檢查程序狀態,若處於靜止就緒,則改為活動就緒,若處於靜止阻塞,則改為活動阻塞

關於排程

*程序控制中,狀態轉換和排程密切相關。
*執行態程序的改變必然產生排程行為
*只要產生新就緒態程序,就需考慮排程策略
*只要是採用搶佔式排程,要檢查新就緒程序是否可搶佔CPU,引起新的排程。

控制併發:

基本控制
程序、PCB、狀態、基本控制過程

合理控制
控制程序的相互影響,得到可再現的正確結果

程序間兩種制約關係:

1.間接相互制約關係:主要源於資源共享,表現為
程序A—印表機資源—程序B(互斥)

2.直接相互制約關係:主要源於程序合作,表現為
程序A寫緩衝—程序B讀緩衝(有序)

1.程序同步的基本概念
1)程序同步的主要任務:
使併發執行的諸程序之間能有效地共享資源和相互合作,
從而使程式的執行具有可再現性。

2)臨界資源
一次僅允許一個程序使用的資源。

3)臨界區
每個程序中訪問臨界資源的那段程式碼叫臨界區。
為了正確同步,對臨界區的程式碼要增加控制

進入區:對欲訪問的臨界資源進行檢。若此刻未被訪問,設正在訪問的標誌
臨界區:訪問臨界資源的程式碼。
退出區:將正在訪問的標誌恢復為未被訪問的標誌
剩餘區:其餘部分

4)同步機制應遵循的規則

實現互斥的方法應符合如下每條原則

空閒讓進:資源使用最基本原則
忙則等待:保證互斥
有限等待:合適時被喚醒防止死等
讓權等待:能主動釋放CPU防止忙等

同步控制的關鍵
主要涉及”判斷”和”修改標誌”操作
不應被打斷(原語,OS核心態執行)

硬體同步機制
*許多計算機提供一些特殊的硬體指令,允許對一個字中的內容進行檢測和修正,
或對兩個字的內容進行交換。利用這些特殊指令解決臨界區問題。
*進入臨界區往往跟其標誌有關,可將標誌看做一個鎖,“鎖開”進入並關鎖,
“鎖關”必須等待,初始時鎖是開啟的。

(1)關中斷

*進入鎖測試前關閉中斷,直到完成鎖測試並上鎖後才能開啟中斷。
程序在臨界區執行期間,系統不響應中斷,從而不引發排程。

*缺點:
*濫用風險
*關中斷時間過長會影響效率,限制CPU交叉執行能力
*不適用於多CPU系統

(2)Test-and-Set指令
boolean TS(boolean *lock)
{
Boolean old;
old=*lock;
*lock=TRUE;
return old;
}
*一個不可分割的原語

為一個臨界資源設定一布林變數lock,初值為false
do{

while TS(&lock) ;
critical section;
lock=FALSE;
remainder section;
}while(TRUE);

(3)利用Swap指令實現程序互斥

*對換指令(intel 80x86中稱XCHG指令),用於交換兩個位元組的內容
void swap(boolean *a, boolean *b)
{boolean temp;
temp=*a;
*a=*b;
*b=temp;
}

*為臨界資源設定一個全域性布林變數lock=false。每個程序一個區域性布林變數key。
do{
key=TRUE;
do{
swap(&lock,&key);
}while(key!=FALSE);
臨界區操作;
lock=FALSE;
剩餘區;
}while(TRUE);

完全利用軟體方法,有很大侷限性,也不適於多程序,現在已很少採用。
硬體指令機械操作可保證鎖開、關操作不被打斷;適用於任意數目的程序。
但等待要耗費CPU時間,不能實現“讓權等待”,從等待程序中隨機選擇一個進入臨界區,
有的程序可能一直選不上,難以實現較為複雜的程序同步問題。