一、進程的基本概念
1.1 多道程序設計
基本思想是允許多個程序同時進入內存并運行,提高CPU的利用率,其目的是為了提高系統(tǒng)效率。

說明:在第一幅圖中在內存中有四個程序,這四個程序是串行執(zhí)行的,因為這里只有一個程序計數(shù)器。當有了多道程序技術之后就得到了第二幅圖中所示的場景,每個程序各自獨立的占用一個邏輯程序計數(shù)器,這樣就達到了一種并發(fā)執(zhí)行的效果,我們從第三幅圖中可以看到多個程序是輪流執(zhí)行的。
1.2 并發(fā)環(huán)境與并發(fā)程序
并發(fā)環(huán)境就是指一段時間間隔內,單處理器上有兩個或兩個以上的程序同時處于開始運行但尚未結束的狀態(tài),并且次序不是事先確定的。而在并發(fā)環(huán)境下執(zhí)行的程序就是并發(fā)程序。
1.3 進程的定義
定義:進程是具有獨立功能的程序關于某個數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進行資源分配和調度的獨立單位。
- 進程是程序的一次執(zhí)行過程,一個程序執(zhí)行多次那是不同的進程
- 是正在運行的程序的抽象,或者說是對
CPU的一個抽象。 - 將一個
CPU變換成多個虛擬的CPU - 系統(tǒng)資源以進程為單位分配,如內存、文件等,操作系統(tǒng)為每個獨立的進程分配了獨立的地址空間。
- 操作系統(tǒng)將
CPU調度給需要的進程,即將CPU的控制權交給某個進程就稱為調度。
1.4 進程控制塊PCB
- 進程控制塊又稱進程描述符或進程屬性
- 操作用于管理控制進程的一個專門的數(shù)據(jù)結構
- 記錄進程的各種屬性,描述進程的動態(tài)變化過程
-
PCB是系統(tǒng)感知進程存在的唯一標志:進程與PCB是一一對應的 - 進程表:所有進程的
PCB集合。進程表的大小往往是固定的,這也就決定了一個操作系統(tǒng)最多支持多少個進程,有時我們稱為系統(tǒng)支持的并發(fā)度。
1.4.1 PCB中需要保存的信息
-
1、進程描述信息
- 進程標識符(
process id),這個標識是唯一的,通常是一個整數(shù) - 進程名,通常基于可執(zhí)行文件名,這是不唯一的
- 用戶標識符(
user id) - 進程組關系
- 進程標識符(
-
2、進程控制信息
- 當前狀態(tài)
- 優(yōu)先級
- 代碼執(zhí)行入口地址
- 程序的磁盤地址
- 運行統(tǒng)計信息(執(zhí)行時間、頁面調度)
- 進程間同步和通信
- 進程的隊列指針
- 進程的消息隊列指針
-
3、所擁有的資源和使用情況
- 虛擬地址空間的使用狀況
- 打開的文件列表
-
4、CPU線程信息
這是當CPU不運行的時候操作系統(tǒng)需要把一些重要的信息記錄下來- 寄存器值(通用寄存器、程序計數(shù)器
PC、程序狀態(tài)字PSW、棧指針) - 指向該進程頁表的指針
- 寄存器值(通用寄存器、程序計數(shù)器
1.4.2 換個角度看PCB的內容

說明:從上圖中可以看到第一列是和進程管理相關的字段,第二列是存儲管理的字段,第三列是文件管理的字段。
二、進程狀態(tài)及狀態(tài)轉換
2.1 進程的三種基本狀態(tài)
即運行態(tài)、就緒態(tài)、等待態(tài)。
- 運行態(tài):占用
CPU,并在CPU上運行 - 就緒態(tài):已經具備運行條件,但由于沒有空閑
CPU,而暫時不能運行 -
等待態(tài):因等待某一事件而暫時不能運行,如等待讀盤結果。又稱為阻塞態(tài)、封鎖態(tài)、睡眠態(tài)。其轉換過程如下:
3
2.2 進程的其他狀態(tài)
-
創(chuàng)建態(tài)
- 已完成創(chuàng)建一個進程所必要的工作,如
PID、PCB - 但尚未同意執(zhí)行該進程,因為資源有限
- 已完成創(chuàng)建一個進程所必要的工作,如
-
終止態(tài)
- 終止執(zhí)行后,進程進入該狀態(tài)
- 可完成一些數(shù)據(jù)統(tǒng)計工作
- 資源回收
-
掛起態(tài)
- 用于調節(jié)負載
- 進程不占用內存空間,其進程映像交換到磁盤上
2.3 五狀態(tài)模型

2.4 七狀態(tài)模型

2.5 Linux狀態(tài)轉換示意圖

說明:這里使用
fork()創(chuàng)建一個進程。淺度睡眠和深度睡眠不同在于前者在睡眠時會接收信號,而后者則不會。正在運行的程序可能因為調試斷點可能出現(xiàn)一個暫停的狀態(tài)。
三、進程隊列
- 操作系統(tǒng)為每一類進程建立一個或多個隊列
- 隊列元素為
PCB - 伴隨進程狀態(tài)的改變,其
PCB從一個隊列進入另一個隊列
7
說明:真實情況下,就緒態(tài)也是排多個隊列。而等待態(tài)由于各自產生的原因(事件)不同而排不同的隊列。
3.1 五狀態(tài)進程模型的隊列模型

四、進程控制
進程控制操作完成進程各狀態(tài)之間的轉換,由具有特定功能的原語(其實就是程序,只是這些程序不許與被中斷)完成。關于進程控制的原語如下:
- 進程創(chuàng)建原語
- 進程撤銷原語
- 阻塞原語
- 喚醒原語
- 激活原語
- 改變進程優(yōu)先級
原語:完成某種特定功能的一段程序,具有不可分割性或不可中斷性,即原語的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷。又稱原子操作。
4.1 進程的創(chuàng)建
- 給新進程分配一個唯一標識以及進程控制塊(沒有被使用的)
- 為進程分配獨立地址空間
- 初始化進程控制塊:設置默認值(如狀態(tài)為
New...) - 設置相應地隊列指針。如:把新進程加到就緒隊列鏈表中
- 主要操作是
UNIX中:fork/exec,Windows中:CreateProcess
4.2 進程的撤銷
也就是結束進程,主要完成的工作:
- 回收進程所占用的資源,如關閉打開的文件、斷開網(wǎng)絡連接、回收分配的內存等
- 撤銷該進程的
PCB - 在
UNIX中使用:exit,Windows中:TerminateProcess
4.3 進程阻塞
處于運行狀態(tài)的進程,在其運行過程中期待某一事件發(fā)生,如等待鍵盤輸入、等待磁盤數(shù)據(jù)傳輸完成、等待其他進程發(fā)送消息。當被等待的事件未發(fā)生時,由進程自己執(zhí)行阻塞原語,使自己由運行態(tài)變?yōu)樽枞麘B(tài)。在UNIX中我們使用wait,在Windows中使用WaitForSingleObject。
4.4 UNIX的幾個進程控制操作
-
fork()通過復制調用進程來建立新的進程,是最基本的進程建立過程。也就是通過復制父進程來創(chuàng)建子進程。 -
exec()包括一些列系統(tǒng)調用,它們都是通過用一段新的程序代碼覆蓋原來的地址空間,實現(xiàn)進程代碼的轉換 -
wait()提供初級進程同步操作,能使一個進程等待另一個進程的結束 -
exit()用來終止一個進程的運行
UNIX中fork()實現(xiàn):
- 為子進程分配一個空閑的進程描述符,即
PCB,在UNIX中又叫proc結構 - 分配給子進程唯一標識
pid - 以一次一頁的方式復制父進程的地址空間,這是一個無用功,因為創(chuàng)建子進程就是為了讓子進程完成與父進程不同的工作,所以父進程的很多內容其實子進程是不需要的。于是在
Linux中采用了寫復制技術COW加快創(chuàng)建進程。 - 從父進程處共享資源,如打開的文件和當前工作目錄等
- 將子進程的狀態(tài)設置為就緒,插入到就緒隊列
- 對子進程返回標識符
0 - 向父進程返回子進程的
pid
9


