程式控制:程式的建立、終止、阻塞、喚醒和切換

劍西樓發表於2017-02-20
程式控制的主要功能是對系統中的所有程式實施有效的管理,它具有建立新程式、撤銷已有程式、實現程式狀態轉換等功能。在作業系統中,一般把程式控制用的程式段稱為原語,原語的特點是執行期間不允許中斷,它是一個不可分割的基本單位。

程式的建立

允許一個程式建立另一個程式。此時建立者稱為父程式,被建立的程式稱為子程式。子程式可以繼承父程式所擁有的資源。當子程式被撤銷時,應將其從父程式那裡獲得的資源歸還給父程式。此外,在撤銷父程式時,也必須同時撤銷其所有的子程式。

在作業系統中,終端使用者登入系統、作業排程、系統提供服務、使用者程式的應用請求等都會引起程式的建立。作業系統建立一個新程式的過程如下(建立原語):
  1. 為新程式分配一個唯一的程式標識號,並申請一個空白的PCB(PCB是有限的)。若PCB申請失敗則建立失敗。
  2. 為程式分配資源,為新程式的程式和資料、以及使用者棧分配必要的記憶體空間(在PCB 中體現)。注意:這裡如果資源不足(比如記憶體空間),並不是建立失敗,而是處於”等待狀態“,或稱為“阻塞狀態”,等待的是記憶體這個資源。
  3. 初始化PCB,主要包括初始化標誌資訊、初始化處理機狀態資訊和初始化處理機控制資訊,以及設定程式的優先順序等。
  4. 如果程式就緒佇列能夠接納新程式,就將新程式插入到就緒佇列,等待被排程執行。

程式的終止

引起程式終止的事件主要有:正常結束,表示程式的任務已經完成和準備退出執行。異常結束是指程式在執行時,發生了某種異常事件,使程式無法繼續執行,如儲存區越界、保護錯、非法指令、特權指令錯、I/O故障等。外界干預是指程式應外界的請求而終止執行,如操作員或作業系統干預、父程式請求和父程式終止。

作業系統終止程式的過程如下(撤銷原語):
  1. 根據被終止程式的識別符號,檢索PCB,從中讀出該程式的狀態。
  2. 若被終止程式處於執行狀態,立即終止該程式的執行,將處理機資源分配給其他程式。
  3. 若該程式還有子程式,則應將其所有子程式終止。
  4. 將該程式所擁有的全部資源,或歸還給其父程式或歸還給作業系統。
  5. 將該PCB從所在佇列(連結串列)中刪除。

程式的阻塞和喚醒

正在執行的程式,由於期待的某些事件未發生,如請求系統資源失敗、等待某種操作的完成、新資料尚未到達或無新工作做等,則由系統自動執行阻塞原語(Block),使自己由執行狀態變為阻塞狀態。可見,程式的阻塞是程式自身的一種主動行為,也因此只有處於執行態的程式(獲得CPU),才可能將其轉為阻塞狀態。

阻塞原語的執行過程是:
  1. 找到將要被阻塞程式的標識號對應的PCB。
  2. 若該程式為執行狀態,則保護其現場,將其狀態轉為阻塞狀態,停止執行。
  3. 把該PCB插入到相應事件的等待佇列中去。

當被阻塞程式所期待的事件出現時,如它所啟動的I/O操作已完成或其所期待的資料已到達,則由有關程式(比如,提供資料的程式)呼叫喚醒原語(Wakeup),將等待該事件的程式喚醒。

喚醒原語的執行過程是:
  1. 在該事件的等待佇列中找到相應程式的PCB。
  2. 將其從等待佇列中移出,並置其狀態為就緒狀態。
  3. 把該PCB插入就緒佇列中,等待排程程式排程。

需要注意的是,Block原語和Wakeup原語是一對作用剛好相反的原語,必須成對使用。 Block原語是由被阻塞程式自我呼叫實現的,而Wakeup原語則是由一個與被喚醒程式相合作或被其他相關的程式呼叫實現的。

程式切換

對於通常的程式,其建立、撤銷以及要求由系統裝置完成的I/O操作都是利用系統呼叫而進入核心,再由核心中相應處理程式予以完成的。程式切換同樣是在核心的支援下實現的,因此可以說,任何程式都是在作業系統核心的支援下執行的,是與核心緊密相關的。

程式切換是指處理機從一個程式的執行轉到另一個程式上執行,這個過程中,程式的執行環境產生了實質性的變化。

程式切換的過程如下:
  1. 儲存處理機上下文,包括程式計數器和其他暫存器。
  2. 更新PCB資訊。
  3. 把程式的PCB移入相應的佇列,如就緒、在某事件阻塞等佇列。
  4. 選擇另一個程式執行,並更新其PCB。
  5. 更新記憶體管理的資料結構。
  6. 恢復處理機上下文。

注意,程式切換與處理機模式切換是不同的,模式切換時,處理機邏輯上可能還在同一程式中執行。如果程式因中斷或異常進入到核心態執行,執行完後又回到使用者態剛被中斷的程式執行,則作業系統只需恢復程式進入核心時所儲存的CPU現場,無需改變當前程式的環境資訊。但若要切換程式,當前執行程式改變了,則當前程式的環境資訊也需要改變。

相關文章