操作系統精髓與設計原理-進程描述和控制

本文若未註明均摘抄自《操作系統精髓與設計原理》:William Stallings著,陳向羣、陳渝譯,機械工業出版社出版第六版

3 進程描述和控制

關鍵字
阻塞態 父進程 進程切換 交換
子進程 搶佔 程序狀態字 內核態
退出態 任務 就緒態 中斷
進程 輪轉 跟蹤 進程控制塊
用戶態 運行態 陷阱 模式切換
進程映像 掛起態 新建態

3.1 什麼是進程

3.1.1 進程和進程控制塊

進程的兩個基本元素是程序代碼和代碼相關的數據集

注:舉例說明的話,熟悉 C/C++ 的讀者可能瞭解,在經由 C/C++ 編譯的程序在運行時的內存佈局分爲以下幾個部分
1. 棧區(stack)由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧
2. 堆區(heap) 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。
3. 全局區(靜態區)(static),全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。 - 程序結束後有系統釋放
4. 文字常量區 —常量字符串就是放在這裏的。 程序結束後由系統釋放
5. 程序代碼區—存放函數體的二進制代碼。
這其中的5就是所謂的進程的程序代碼,而1-4就是所謂的代碼相關的數據集。這兩種概念間微妙的差別需要讀者細細品味

以上從程序運行的視角來對進程的內存進行了一番管中窺豹。如果從操作系統的角度觀察的話,進程的內存中還有更多的細節需要注意。

在進程執行時,任何一個時間進程的所有細節都可以被以下元素唯一的表達

  • 標識符
  • 狀態
  • 優先級
  • 程序計數器
  • 內存指針:包括程序代碼和進程相關數據的指針
  • 上下文數據:進程執行時處理器中寄存器的數據
  • I/O狀態信息:包括顯式的I/O請求、分配給進程的I/O設備(例如磁盤驅動器)和被進程使用的文件列表等
  • 記賬信息:可能包括處理器時間總和、使用的時鐘數總和、時間限制、記賬號等

前述的列表信息存放在一個叫做進程控制塊(如下圖)的數據結構中

圖3.1

進程控制塊是操作系統能夠支持多進程和提供多處理的關鍵概念,可以說進程是有程序代碼和相關進程控制塊組成。

3.2 進程狀態

單個進程的行爲可以被一串指令序列描述,這個序列被稱爲進程的軌跡,這個概念的含義就如同看上去那樣膚淺,只是起了個名字而已。

考慮一個非常簡單的例子,假設有軌跡如下的三個進程A、B、C

圖3.3

現在從處理器的角度來看這些軌跡。爲了簡化討論,假設這些進程沒有使用虛擬內存——也就代表這些進程都完全被載入到了內存中,並且假設這些進程不會調用I/O設備,也即不會長時間的等待響應。此外,存在一個調度器使處理器從一個進程切換到另外一個進程。

在圖3.4中,顯示了這三個進程被處理器“同時”處理時可能出現的處理過程,其中陰影部分代表由調度器執行的代碼

圖3.4

博主認爲這個示例和兩張圖尤其值得仔細理解

3.2.1 兩狀態進程模型

在這種最簡單的模型中,一個進程可以處於兩種狀態中的一種:運行和未運行。這種模型雖然簡單,但所有現代的進程模型特性都是圍繞這個中心發展而來的。一個典型的兩狀態進程模型如下圖所示:

圖3.5

3.2.2 進程的創建和終止

在對上述最簡單的進程模型進行擴充之前,需要先討論一下進程的創建和終止的細節

進程的創建

如3.1.1所述,當一個新進程被創建時,操作系統需要在進程列表中爲它創建一個與其他進程格式相同的數據結構用於記錄和管理它的狀態。

通常有四種事件會導致進程的創建

表3.1 導致進程創建的原因

事件 說明
新的批處理作業 通常位於磁帶或者磁盤中的批處理作業控制流程被提供給操作系統。當操作系統準備接納新工作時,它將讀取下一個作業控制命令
交互登陸 終端用戶登錄到系統
操作系統因爲提供一項服務而被創建 操作系統可以創建一個進程,代表用戶程序執行的一個功能,使用戶無需等待(如控制打印機的進程)
由現有的進程派生 基於模塊化的考慮,或者爲了開發並行性,用戶程序可以指示創建多個進程

當操作系統爲另一個進程顯式的請求創建一個新進程時,這個動作被稱爲進程派生。當一個進程派生另一個進程的時候,前一個稱作父進程,被派生的叫做子進程。在大多數情況下,父子進程間需要進行通信和合作。對於程序員來說這是一件比較困難的任務,相關內容將在第五章講述

進程終止

表3.2 導致進程終止的原因

事件 說明
正常完成 進程自行執行一個操作系統服務調用,表示他已經結束運行
超時 進程運行時間超過規定的時限。可以測量很多種類型的時間,包括總的運行時間(“掛鐘時間”)、花費在執行上的時間以及對於交互進程從上一次用戶輸入到當前時刻的時間總量
無可用內存 系統無法滿足進程需要的內存空間
越界 進程試圖訪問不允許訪問的內存單元
保護錯誤 進程試圖使用不允許使用的資源或文件,或者試圖以一種不正確的方式使用,入往只讀文件中寫
算數錯誤 進程試圖進行被禁止的計算,如除零運算或者存儲大於硬件可以承載的數字
時間超出 進程等待某一事件發生的時間超過了規定的最大值
I/O失敗 在輸入或輸出期間發生錯誤,如找不到文件、在超過規定的最多嘗試次數後依然讀/寫失敗(如遇到磁盤壞道)或者無效操作(如從行式打印機中讀)
無效指令 進程試圖執行一個不存在的指令(通常是由於錯誤的將數據當作指令進行執行)
特權指令 進程視圖使用爲操作系統保留的指令
數據誤用 錯誤類型或未初始化的一塊數據
操作員或操作系統干涉 由於某些原因,操作員或操作系統主動終止進程(如程序進入死鎖狀態,被手工終止)
父進程終止 當一個子進程所屬的父進程終止,子進程可能也隨之終止
父進程請求 父進程通常具有結束子進程的權限

3.2.3 五狀態模型

在兩狀態進程模型中,我們假設進程是沒有I/O帶來的延遲響應的,但現實中進程大多數情況下都要與I/O設備進行溝通,這時候兩狀態進程模型就不夠描述進程的所有狀態了,因此擴充了五狀態模型。五狀態模型的形式如下:

圖3.6

  • 運行態:該進程正在執行。在本章中假設計算機只有一個處理器,這樣的話同一時間只能有最多一個進程處於運行態。
  • 就緒態:進程做好了準備,只要有機會就會開始執行。
  • 阻塞/等待態:進程在某些時間發生前不能執行,如I/O完成。
  • 新建態:剛剛創建的進程,操作系統還沒有把他加入到進程列表中。通常是進程控制塊已經創建但是還沒有加載到內存中的新進程。
  • 退出態:操作系統從可執行進程組中釋放出的進程,或者是因爲他自身停止了,或者是因爲某種原因被取消。

當進程處於新建態時,操作系統所需要的關於進程的信息保存在內存中的進程表中,但是進程自身還沒進入內存,就是即將執行的程序代碼不在內存中,也沒有爲這個程序相關的數據分配內存空間。當進程處於新建態時,程序保留在外存中。

圖3.6顯示了五種狀態以及在這些狀態間切換的事件類型,這裏舉例一些狀態切換時可能的情況:

  • 運行→就緒:這類轉換最常見的原因是,正在運行的進程到達了“允許被不中斷的執行”的時間上限
  • 運行→阻塞:如果進程請求它必須等待某些事件,則進入阻塞態。對操作系統而言通常以系統服務調用的形式發出。

在兩狀態模型中舉出的例子中加入阻塞的情況後,就是一個稍微複雜的例子,圖3.7顯示了每個進程在狀態間的轉換,圖3.8a給出了可能實現的排隊規則,有兩個隊列:就緒隊列和阻塞隊列。進入系統的每個進程被放置在就緒隊列中,操作系統將選擇另一個進程運行時,就會從就緒隊列中選擇。

當一個正在運行的進程被移出處理器時,它根據情況或者進入就緒或阻塞隊列,或者被終止。

最後,當一個時間發生時,所有位於阻塞隊列中等待這一事件的進程將被轉移到就緒隊列中

圖3.7

圖3.8

3.2.4 被掛起的進程

交換的需要

前面描述的三種基本狀態(運行態、就緒態、阻塞態)提供了一套能讓進程真正穩定運行起來的進程模型。如果單純想運行程序,這套模型已經OK了,但很多時候,在這套進程模型的基礎上添加一些其他的特性,能夠進一步的提升進程的執行效率。

在最初的兩狀態模型中,我們層假設所有的進程都被加載在內存中,也即沒有使用虛擬內存。因此前述的所有例子中,所有隊列中的進程都必須駐留在內存中。當一個進程正在等待I/O的時候處理器可以轉移到另一個進程,但處理器大多數時候都比I/O快的多,以至於所有內存中的進程都在等待I/O的情況也很常見

這個問題常見的解決方法就是交換,包括把內存中的某個進程的一部分或全部轉移到磁盤中。當內存中沒有處於就緒態的進程時,操作系統就會把被阻塞的進程換出到磁盤中的“掛起隊列”(suspend queue),這是暫時保存從內存中被驅逐出的進程隊列,或者說是被掛起的進程隊列。

“交換”(swapping)也是一個I/O操作,有些情況下可能會讓效率更加惡化,但由於磁盤I/O一般是系統中最快的I/O,所以交換的效果通常是正面的。

然而這個推理也帶來了一個難題,當進程被掛起後,它的狀態是處於阻塞態。顯然把一個阻塞態的進程拉回到內存中毫無意義,因此就需要爲掛起態的進程準備兩種狀態:掛起/阻塞、掛起/就緒。這樣的進程模型如下圖所示。

這裏寫圖片描述

在虛擬內存方案中,可能會執行到只有一部分內容在內存中的進程,如果有足夠多的活動進程,並且所有進程都有一部分在內存中,則有可能導致虛擬內存系統崩潰。

以下列出一些新的比較重要的狀態轉換的情況:

  • 阻塞/掛起→阻塞/就緒:如果等待的時間發生了,則處於阻塞/掛起的進程可以轉換到就緒/掛起態。但這要求操作系統必須能夠得到被掛起進程的狀態信息(這意味着進程的一部分,至少是狀態信息需要被保留在內存中)
  • 各種狀態→退出:在某些操作系統中,父進程有權力終止子進程,這就決定了在這些系統中,一個進程可以從任何狀態轉入退出態。

掛起的其他用途

到目前爲止,掛起的進程的概念與不在內存中的進程的概念是等價的

表3.3 導致進程掛起的原因

事件 說明
交換 操作系統需要釋放足夠的內存空間,以調入並執行處於就緒/掛起態的進程
其他OS原因 操作系統可能掛起後臺進程或工具程序進程,或者被懷疑導致問題的進程
交互式用戶請求 用戶可能希望主動地掛起一個程序的執行,目的是調試或者與一個資源的使用進行連接
定時 一個進程可能會週期性的執行(例如記賬或程序監視進程),而且可能在等待下一個時間間隔時被掛起
父進程請求 父進程可能會希望掛起後代進程的執行,以檢查或修改掛起的進程,或者協調不同的後代進程之間的行爲

3.3 進程描述

我們可以把操作系統看作是管理系統資源的實體。負責協調進程、I/O設備、處理器時間片等資源高效的運行。在下圖中,進程P1正在運行,該進程至少有一部分在內存中,並且還控制着兩個I/O設備;進程P2也在內存中,但由於正在等待P1佔用的I/O資源而被阻塞。Pn已經被換出,因此是掛起的。

圖3.10

3.3.1 操作系統的控制結構

操作系統爲了管理進程和資源,必須掌握關於每個進程和資源當前狀態的信息。基本上所有操作系統維護的信息都可以分爲內存、I/O、文件、進程四類

圖3.11

內存表用於跟蹤內存和虛擬內存,內存表必須包含以下內容。

  • 分配給進程的內存
  • 分配給進程的外存
  • 內存塊或虛擬內存塊的任何保護屬性,如哪些進程可以訪問某些共享內存區域
  • 管理虛擬內存所需要的任何信息

7、8章主要講述用於內存管理的信息結構

I/O表管理計算機系統中的I/O設備和通道。11章將詳細講述I/O管理。

文件表提供關於文件是否存在、文件在外存中的位置、當前狀態和其他屬性信息。這方面內容將在12章着重講述

進程表也是操作系統需要維護的重要信息表之一,本節剩餘的部分將着重講述進程表。

在圖3.11中給出了4種不同的表,須知這四種表是相互關聯甚至是交叉引用的。比如內存、I/O和文件是代表進程而被管理的,另外文件表中的文件也可以通過I/O設備訪問,有時這些文件也位於內存或虛擬內存中,等等。

3.3.2 進程控制結構

操作系統在管理和控制進程時,必須指導進程的位置和進程屬性。

進程位置

一個進程包括足夠的內存空間,以保存進程本身的數據和程序;此外,程序的執行通常涉及跨進程的調用和跟蹤過程調用的棧(系統棧,推薦閱讀);最後,操作系統爲每個進程創建了許多屬性,這些屬性的集合叫做進程控制塊(process control block)。程序、數據、棧、屬性的集合稱作進程映像(process image)。

進程映像的維持依賴於使用的內存管理方案現代操作系統假定分頁硬件允許用不連續的物理內存來支持部分常駐內存的進程。在任何時刻,進程映像可以分別在內存和外存中保留自己的一部分。所以操作系統維護的進程表必須表明每個進程映像中每頁的位置。

進程屬性

複雜的多道程序系統需要關於每個進程的大量信息。表3.5列出了操作系統所需要的每個進程信息的簡單分類。

表3.5 進程控制塊中的典型元素

表3.5-1
表3.5-2

特別注意的是,所有處理器的設計都包括一個或一組通常稱做程序狀態字(Program Status Word, PSW)的寄存器,它包含狀態信息。PSW通常包含條件碼以及其他狀態信息。先前學習過單片機的朋友一定會對這個縮寫感到親切。

圖3.13給出了虛擬內存中進程映像的結構。每個進程映像包括一個進程控制塊、用戶棧、金成德專用地址空間以及與別的進程共享的任何其他地址空間。在這個圖中,每個進程映像表現爲一段地址相鄰的區域,但在實際的實現中可能不是這種情況。這具體取決於內存管理方案和操作系統組織控制結構的方法。

圖3.13

進程控制塊的作用

進程控制塊包含操作系統所需要的關於進程的所有信息。而系統中負責調度、資源分配、中斷處理、性能監控和分析的模塊都可以讀取和修改他們。

這爲進程映像的保護帶來了設計難題,具體表現爲下面兩個問題:

  • 一個例程(如中斷處理程序)中有錯誤,可能會破壞進程控制塊,近而破壞了系統對受影響的進程的管理能力。
  • 進程控制塊的結構或語義的設計變化可能會影響到操作系統中的許多模塊。

這些問題可以通過一個處理例程來專門處理,處理例程負責保護進程控制塊,仲裁讀寫請求。

3.4 進程控制

3.4.1 執行模式

大多數處理器支持至少兩種執行模式。某些指令只能在特權模式下運行,包括讀取或改變諸如程序狀態字之類的控制寄存器的指令、原始I/O指令與內存管理相關的指令、以及訪問部分受限的內存區域。

非特權態通常被稱爲用戶態,特權態一般被稱作內核態,也稱作控制態或系統態。內核態指的是操作系統的內核,這是操作系統中包含重要系統功能的部分。表3.7列出了操作系統內核中通常可以找到的功能。

表3.7 操作系統內核的典型功能

進程管理 內存管理 I/O管理 支持功能
進程的創建和終止 給進程分配地址空間 緩衝區管理 中斷處理
進程的調度和分派 交換 給進程分配I/O通道和設備 記賬
進程切換 頁和段的管理 監視
進程同步以及對進程間通信的支持
進程控制塊的管理

使用兩種模式是爲了保護操作系統和重要的操作系統表(如進程控制塊)不受用戶程序的干涉。在內核態下,軟件具有對處理器以及所有指令、寄存器和內存的控制能力,這一級別的控制對用戶程序不是必須的,並且不應該被用戶程序訪問。

在程序狀態字中有一位表示執行模式,這一位應某些事件的要求而改變,如:當用戶調用一個操作系統服務或中斷觸發系統例程的執行時,執行模式被設爲內核態,而當從系統服務返回到用戶程序時,執行模式會被設回到用戶態。

3.4.2 進程創建

一旦操作系統決定創建一個新進程,以下步驟會被依次執行:

  1. 給新進程分配一個唯一的進程標識符,並在主進程表中增加一個新表項對應這一進程。
  2. 給進程分配空間。包括進程映像中的所有元素。
  3. 初始化進程控制塊。進程標識符部分包括進程ID和其他相關的ID,如父進程的ID等;處理器狀態信息部分大多數項目被初始化爲0,除了程序計數器(被設置爲程序入口點)和系統棧指針(用來定義進程棧邊界);進程控制信息部分被初始化成默認值和爲該進程所請求的屬性。例如,進程狀態在典型的情況下被初始化成就緒或就緒/掛起;除非顯式的請求更高的優先級,否則默認最低優先級;除非顯式的請求或從父進程繼承,否則進程最初不用有任何資源。
  4. 設置正確的連接。如將進程排入它所屬的調度隊列中
  5. 創建或擴充其他數據結構。

3.4.3 進程切換

關於進程切換的問題,首先什麼事件會觸發進程的切換?以及,切換模式與切換進程有什麼區別?最後,爲實現進程切換,操作系統必須對他控制的各種數據結構做些什麼?

何時切換進程

進程切換可以在操作系統從當前正在運行的進程中重獲控制權的任何時刻發生,表3.8給出了可能把控制權交給操作系統的事件。

大多數操作系統區分兩種類型的系統中斷。一種稱爲中斷,另一種稱爲陷阱。中斷與當前正在運行的進程無關,如完成一次I/O操作,陷阱與當前正在運行的進程所產生的錯誤或異常條件相關,如非法的文件訪問。常見的普通中斷包括時鐘中斷、I/O中斷、內存失效。

表3.8 進程執行中的中斷機制

機制 原因 使用
中斷 當前指令的外部執行 對異步外部事件的反應
陷阱 與當前指令的執行相關 處理一個錯誤或異常條件
系統調用 顯式請求 調用操作系統函數

操作系統可能被來自正在執行的程序的系統調用激活,例如,一個用戶進程正在執行一條請求I/O的操作指令,這個調用導致轉移到作爲操作系統代碼一部分的一個例程上執行。通常使用系統調用會導致把用戶進程設置爲阻塞態。

模式切換

如果有未處理的中斷,處理器需要做以下工作:

  1. 把程序計數器置爲中斷處理程序的開始地址
  2. 從用戶態切換到內核態

隨後處理器繼續取指階段,並取中斷處理程序的第一條指令,隨後處理器將爲中斷提供服務。此時,被中斷的進程的上下文被保存在中斷程序的進程控制塊中。保存的上下文中包含中斷處理可能改變的信息和恢復被中斷程序所需要的任何信息。

在大多數操作系統中,中斷的發生並不是必須伴隨進程的切換,可能被中斷的進程會在中斷處理程序結束後繼續運行。

進程狀態的變化

發生模式切換可以不改變正處於運行態的進程狀態,在這種情況下,保存上下文環境和以後回覆上下文環境只需要很少的開銷。相比之下改變進程狀態的工作則要多很多,完整的切換進程步驟如下:

  1. 保存處理器上下文環境,包括程序計數器和其他寄存器
  2. 更新當前處於運行態進程的進程控制塊,包括更新進程的狀態,更新其他的相關域,包括離開運行態的原因和記賬信息。
  3. 將進程的進程控制塊移動到相應的隊列
  4. 選擇另一個進程執行,這方面內容在9-10章着重討論
  5. 更新所選進程的進程控制塊,包括將進程的狀態變爲運行態
  6. 更新內存管理的數據結構,這方面在7-8章着重討論
  7. 恢復處理器在被選擇的進程最近一次切換出運行狀態時的上下文環境,這可以通過載入程序計數器和其他寄存器以前的值來實現

可以看出,進程狀態切換時,除了切換上下文,還需要額外維護、更新很多用於進程調度的數據結構,因此相比模式切換需要作更多工作

3.5 操作系統的執行

此處回憶第二章給出的兩個事實:
- 操作系統本質上和軟件是相同的
- 操作系統經常釋放控制權,並且依賴處理器才能恢復控制權

3.5.1 無進程的內核

在許多老的操作系統中,進程的概念只適用於用戶程序,用戶程序只具有進程棧,不具有內核戰。操作系統在底層負責所有的進程調度工作,並且擁有自己的內存區域和系統棧,在內核態下被作爲一個完整且獨立的實體執行。

3.5.2 在用戶進程中執行

在面向較小的機器(PC、工作站)設計的操作系統中,常見的方法是在用戶進程的上下文中執行幾乎所有操作系統軟件。如圖3.15b所示,任何時候每個進程映像不僅包含圖3.13中列出的區域,還包括內核程序的程序代碼、數據和棧區域。

圖3.15

圖3.13

圖3.16

相比無進程的內核,該方法的一個顯著優點在於,一個用戶程序被中已使用某些操作系統進程,然後被恢復,這樣的操作不再需要兩次進程切換爲代價。

3.5.3 基於進程的操作系統

圖3.15c顯示的是另一種方案,即把操作系統作爲一組進程來實現。這種方案的優點在於,它促使使用模塊化的操作系統,並且模塊間有最小的、簡明的接口

3.6 安全問題

操作系統對於每個進程都關聯了一套權限。規定了進程可以獲得的資源,包括內存區、文件、特權系統指令等。一般最高級別的權限指的是管理員、超級用戶或根用戶的訪問權限,根用戶進程可以安全地控制系統,增加修改程序和文件,對進程進行監控,發送和接受網絡流量和改變權限。

3.6.1 系統訪問威脅

系統訪問威脅分爲兩類,入侵者和惡意軟件。

入侵者

對於安全,最普遍的威脅是入侵者,通常是指黑客和解密人員,[ANDE80]中定義了三種類型的入侵者:

冒充者:沒有授權的人通過穿透系統的訪問控制去使用一個合法的用戶賬號

濫用職權者:一個合法的用戶訪問沒有授權的數據、程序或資源,或者用戶具有這種訪問授權,但濫用了他的權限

祕密用戶:一個用戶獲得了系統的管理控制,然後使用這種控制來逃避審計和訪問控制,或者廢止審查收集。

惡意軟件

惡意軟件是利用計算機系統漏洞的程序。惡意軟件分爲兩大類,一類需要宿主程序,另一類是獨立運行的。前者也被稱爲寄生,本質上使一些不能獨立於實際應用程序,通用用程序或系統程序而存在的片段,例如病毒、邏輯炸彈和後門。後者則是獨立並可以被操作系統調度和運行的程序,例如蠕蟲和殭屍程序。

也可以按是否可以複製將惡意軟件分類,通過觸發器激活的程序或者片段是無法複製的,如邏輯炸彈、後門和殭屍程序。另一種則在運行後可能產生一個或者多個自身的副本,這些副本將在該系統或其他系統被激活以進行持續的傳播,例如病毒和蠕蟲。

3.6.2 對抗措施

入侵檢測

RFC2828對入侵檢測的定義如下:

入侵檢測是一種安全服務,通過監視和分析系統事件發現視圖通過未經授權的方法訪問系統資源的操作,並對這種操作提供實時或準時的警告。

入侵檢測系統(IDS)可以分爲如下幾類:

  • 基於宿主的IDS:監控單個宿主的特徵和發生在宿主上的事件
  • 基於網絡的IDS:監控特定的網絡段或者網絡設備流量。

IDS由三部分組成:

  • 感應器
  • 分析器
  • 用戶界面

認證

在許多計算機安全內容中,用戶認證是一個主要的構建模塊和最初防線。RFC2828對用戶認證做了如下定義:

系統實體定義了驗證和確認的過程,認證過程包括以下兩步:
- 確認步驟:對於安全系統,提出了標識符。
- 驗證步驟:提出或產生認證信息,用來證實在實體與標識符之間的綁定。

博主:一言以蔽之,前者區分用戶是誰(用戶名),後者確認用戶的真實性(密碼)

3.7 UNIX SVR4進程管理

UNIX採用圖3.15b中的模型,用戶進程在用戶態執行用戶程序和實用程序,在內核態下運行屬於內核的指令。當產生異常或中斷或系統調用時,用戶進程進入內核態。

3.7.1 進程狀態

UNIX有九種進程狀態,如下圖下表所示:

圖3.17

表3.9 UNIX進程狀態

進程狀態 說明
用戶運行 在用戶態下執行
內核運行 在內核態下執行
就緒 只要內核調度到就立刻準備運行
睡眠 在某事件發生前不能執行,且進程在內存中(一種阻塞態)
就緒/被交換 進程已經就緒,但不在內存中
睡眠/被交換 進程正在等待一個事件,並且不在內存中
被強佔 進程打算從內核返回到用戶態,但內核搶佔它並做了進程切換,以調度另一個進程
創建 進程剛被創建,還沒做好運行準備
僵死 進程不再存在,但它留下了一個記錄,該記錄可由其父進程收集

3.7.2 進程描述

UNIX中的進程映像被組織爲用戶上下文、寄存器上下文、系統級上下文三部分

表3.10

用戶級上下文包括用戶程序的基本成分,可由已編譯的目標文件直接產生,包含數據區和正文區。
寄存器上下文在進程沒有運行時保存處理器狀態。
系統級上下文包括操作系統管理進程所需要的其餘信息,由靜態和動態區構成,靜態區部分是進程表項,其大小一直不變。用戶區,即U區,包含了內核在進程的上下文環境中執行時所需要的額外進程控制信息,當進程調入或調出內存時也會用到它。

表3.11

表3.12

3.7.3 進程控制

UNIX中的進程創建通過內核系統調用fork實現,當產生一個fork請求時,操作系統執行以下功能[BACH86]

  1. 爲新進程在進程表中分配空項
  2. 爲子進程附一個唯一標識符
  3. 做一個父進程上下文的邏輯副本,不包括共享內存區
  4. 增加父進程擁有的全部文件的計數器,表示有另一個進程現在也擁有這些文件
  5. 把子進程設置爲就緒態
  6. 向父進程返回子進程的進程號;對子進程返回0

以上操作在父進程的內核態中完成。

3.8 小結

現代操作系統中最基本的構件是進程,操作系統的基本功能就是創建、管理和終止進程。

發佈了25 篇原創文章 · 獲贊 25 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章