進程的控制
進程控制塊(PCB)
進程控制塊(Processing Control Block),是操作系統核心中一種數據結構,主要表示進程狀態。其作用
是使一個在多道程序環境下不能獨立運行的程序(含數據),成為一個能獨立運行的基本單位或與其它進程並發執行的進程。或者說,OS是根據PCB來對並發執行的進程進行控制和管理的, 它存放着操作系統用於描述進程情況及控制進程運行所需的全部信息。
進程控制塊(PCB)是系統為了管理進程
設置的一個專門的數據結構。系統用它來記錄進程的外部特征,描述進程的運動變化過程。同時,系統可以利用PCB來控制和管理進程,所以說,PCB(進程控制塊)是系統感知進程存在的唯一標志。
PCB通常記載進程之相關信息,包括:
- 程序計數器:接着要運行的指令地址。
- 進程狀態:可以是new、ready、running、waiting或 blocked等。
- CPU暫存器:如累加器、索引暫存器(Index register)、堆棧指針以及一般用途暫存器、狀況代碼等,主要
- 用途在於中斷時暫時存儲數據,以便稍后繼續利用;其數量及類因電腦架構有所差異。
- CPU排班法:優先級、排班隊列等指針以及其他參數。
- 存儲器管理:如標簽頁表等。
- 會計信息:如CPU與實際時間之使用數量、時限、賬號、工作或進程號碼。
- 輸入輸出狀態:配置進程使用I/O設備,如磁帶機。
進程控制塊PCB的組織方式:
- 線性表方式:不論進程的狀態如何,將所有的PCB連續地存放在內存的系統區。這種方式適用於系統中進程數目不多的情況。
- 索引表方式:該方式是線性表方式的改進,系統按照進程的狀態分別建立就緒索引表、阻塞索引表等。
- 鏈接表方式:系統按照進程的狀態將進程的PCB組成隊列,從而形成就緒隊列、阻塞隊列、運行隊列等。
進程的創建
在系統中每當出現了創建新進程的請求后,OS便調用進程創建原語 Creat按下述步驟創建一個新進程:
-
申請空白PCB,為新進程申請獲得唯一的數字標識符,並從PCB集合中索取一個空白PCB。
-
為新進程分配其運行所需的資源,包括各種物理和邏輯資源,如內存、文件、IO設備和CPU時間等。
這些資源或從操作系統或僅從其父進程獲得。新進程對這些資源的需求詳情一般也要提前告知操作系統或其父進程。
例如:為新進程的程序和數據以及用戶棧分配必要的內存空間時,操作系統必須知道新進程所需內存的大小:
①對於批處理作業,其大小可在用戶提出創建進程要求時提供;
②若是為應用進程創建子進程,也應是在該進程提出創建進程的請求中給出所需內存的大小;
③對於交互型作業,用戶可以不給出內存要求而由系統分配一定的空間;如果新進程要共享某個已在內存的地址空間(即已裝入內存的共享段),則必須建立相應的鏈接
-
初始化進程控制塊(PCB)。
PCB的初始化包括:
①
初始化標識信息
,將系統分配的標識符和父進程標識符填入新PCB中; ②
初始化處理機狀態信息
,使程序計數器指向程序的入口地址,使棧指針指向棧頂; ③
初始化處理機控制信息
,將進程的狀態設置為就緒狀態或靜止就緒狀態,對於優先級,通常是將它設置為最低優先級,除非用戶以顯式方式提出高優先級要求。 -
如果進程就緒隊列能夠接納新進程,便將新進程插入就緒隊列。
進程的終止
引起進程終止的事件
-
正常結束:表示進程的任務已經完成,准備退出運行。在任何系統中,都應有個用於表示進程已經運行完成的指示。
-
異常結束:是指進程在運行時發生了某種異常事件,使程序無法繼續運行。
常見的異常事件有:
①越界錯,這是指程序所訪問的存儲區,已越出該進程的區域;
②保護錯,指進程試圖去訪問一個不允許訪問的資源或文件,或者以不適當的方式進行訪問,例如,進程試圖去寫一個只讀文件;
③非法指令,指程序試圖去執行一條不存在的指令。出現該錯誤的原因可能是程序錯誤地轉移到數據區,把數據當成了指令:
④特權指令錯,指用戶進程試圖去執行一條只允許OS執行的指令;
⑤運行超時,指進程的執行時間超過了指定的最大值;
⑥等待超時,指進程等待某事件的時間超過了規定的最大值;
⑦算術運算錯,指進程試圖去執行一個被禁止的運算,例如,被0除:⑧IO故障,這是指在IO過程中出錯
-
外界干預:是指進程應外界的請求而終止運行。
這些干預有:
①操作員或操作系統干預,指如果系統中發生了某事件,例如,發生了系統死鎖,由操作員或操作系統采取終止某些進程的方式使系統從死鎖狀態中解救出來;
②父進程請求,指當子進程已完成父進程所要求的任務時,父進程可以提出請求結束該子進程;
③因父進程終止,指當父進程終止時,它的所有子進程也都應當結束,因此,OS在終止父進程的同時,也將它的所有子孫進程終止。
進程終止的過程
如果系統中發生了要求終止進程的某事件,OS便調用進程終止原語,按下述過程去終止指定的進程:
- 根據被終止進程的標識符,從PCB集合中檢索出該進程的PCB,從中讀出該進程的狀態;
- 若被終止進程正處於執行狀態,應立即終止該進程的執行,並置調度標志為真,用於指示該進程被終止后應重新進行調度;
- 若該進程還有子孫進程,還應將其所有子孫進程也都予以終止,以防它們成為不可控的進程;
- 將被終止進程所擁有的全部資源或者歸還給其父進程,或者歸還給系統
- 將被終止進程(PCB)從所在隊列(或鏈表)中移出,等待其它程序來搜集信息。
進程的阻塞和喚醒
引起進程阻塞和喚醒的事件
- 向系統請求共享資源失敗:進程在向系統請求共享資源時,由於系統已無足夠的資源分配給它,此時進程因不能繼續運行而轉變為阻塞狀態。例如,一進程請求使用打印機,由於系統已將打印機分配給其它進程,已無可以再可分配的打印機,這時請求者進程只能被阻塞,僅在其它進程釋放出打印機時,請求進程才被喚醒。
- 等待某種操作的完成:當進程啟動某種操作后,如果該進程必須在該操作完成之后才能繼續執行,則應先將該進程阻塞起來,以等待操作完成。例如,進程啟動了某IO設備,如果只有在IO設備完成了指定的IO操作任務后進程才能繼續執行,則該進程在啟動了IO設備后便應自動進入阻塞狀態去等待。在IO操作完成后,再由中斷處理程序將該進程喚醒。
- 新數據尚未到達:對於相互合作的進程,如果一個進程需要先獲得另一進程提供的數據后才能對該數據進行處理,只要其所需數據尚未到達,進程便只有阻塞。例如,有兩個進程,進程A用於輸入數據,進程B對輸入數據進行加工。假如A尚未將數據輸入完畢,則進程B將因沒有所需處理的數據而阻塞;一旦進程A把數據輸入完畢,便可去喚醒進程B
- 等待新任務的到達:在某些系統中,特別是在網絡環境下的Os,往往設置一些特定的系統進程,每當這種進程完成任務后便把自己阻塞起來,等待新任務的到來。例如在網絡環境中的發送進程,其主要任務是發送數據包,若已有的數據包已全部發送完成,而又無新的數據包發送,這時發送進程將把自己阻塞起來;僅當有新的數據包到達時,才將發送進程喚醒。
進程阻塞的過程
正在執行的進程,如果發生了上述某事件,進程便通過調用阻塞原語 block
將自己阻塞。可見,阻塞是進程自身的一種主動行為。
進入 block過程后,由於該進程還處於執行狀態,所以應先立即停止執行,把進程控制塊中的現行狀態由“執行”改為阻塞
,並將PCB插入阻塞隊列
。
如果系統中設置了因不同事件而阻塞的多個阻塞隊列,則應將本進程插入到具有相同事件的阻塞隊列。
最后,轉調度程序進行重新調度,將處理機分配給另一就緒進程,並進行切換,亦即,保留被阻塞進程的處理機狀態,按新進程的PCB中的處理機狀態設置CPU的環境。
進程喚醒的過程
當被阻塞進程所期待的事件發生時,比如它所啟動的IO操作已完成,或其所期待的數據已經到達,則由有關進程(比如提供數據的進程)調用喚醒原語 wakeup
,將等待該事件的進程喚醒。
wakeup執行的過程是:首先把被阻塞的進程從等待該事件的阻塞隊列中移出,將其PCB中的現行狀態由阻塞改為就緒
,然后再將該PCB插入到就緒隊列
中。
應當指出,block原語和 wakeup原語是一對作用剛好相反的原語。在使用它們時,必須成對使用,即如果在某進程中調用了阻塞原語,則必須在與之相合作的、或其它相關的進程中安排一條相應的喚醒原語,以便能喚醒被阻塞進程;否則,阻塞進程將會因不能被喚醒而永久地處於阻塞狀態,再無機會繼續運行
線程的掛起和激活
進程的掛起
當系統中出現了引起進程掛起的事件時,OS將利用
掛起原語 suspend
將指定進程或處於阻塞狀態的進程掛起。
suspend的執行過程是:首先檢查被掛起進程的狀態,若處於活動就緒狀態,便將其改為靜止就緒;對於活動阻塞狀態的進程,則將之改為靜止阻塞;為了方便用戶或父進程考査該進程的運行情況,而把該進程的PCB復制到某指定的內存區域最后,若被掛起的進程正在執行,則轉向調度程序重新調度。
進程的激活過程
當系統中發生激活進程的事件時,OS將利用
激活原語 active
,將指定進程激活。激活原語先將進程從外存調入內存,檢査該進程的現行狀態,若是靜止就緒,便將之改為活動就緒;若為靜止阻塞,便將之改為活動阻塞。
假如采用的是搶占調度策略,則每當有靜止就緒進程被激活而插入就緒隊列時,便應檢査是否要進行重新調度,即由調度程序將被激活的進程與當前進程兩者的優先級進行比較,如果被激活進程的優先級低,就不必重新調度;否則,立即剝奪當前進程的運行,把處理機分配給剛剛被激活的進程