進程管理概述
爲了提升計算機處理機的利用率,計算機學者引入了多道程序設計的概念,即在操作系統中同時可以運行多道程序。爲了便於管理操作系統中同時運行的多個程序,就引入了進程的概念。
可以給進程下這麼一個定義,進程是一個程序動態運行的過程,是操作系統分配資源的基本單位。其實引入進程的概念就是爲了給多道程序隔離資源。對於進程的管理可以分爲這麼幾個方向:進程控制、進程同步以及進程的調度。
如何描述一個進程?
從結構上看,進程由程序段、數據段以及進程控制塊(PCB)組成。程序段是指進程運行的程序,數據段指程序運行所需的數據,進程控制塊是對運行中的進程的一種動態描述,它包含了操作系統控制進程所需的所有信息。爲什麼說PCB是對進程的一種動態描述呢?因爲進程運行的過程中,操作系統是會不斷地去修改進程的PCB。
下面來看看,PCB中存儲了什麼信息,這樣才知道操作系統如何通過PCB管理進程。
進程標識信息:爲操作系統唯一的標識一個進程。
處理機狀態信息:記錄了當前進程運行時處理機內的內容,是進程切換和恢復的必要信息。
進程調度信息:存放進程調度有關信息。如:進程狀態、進程優先級等
進程控制信息:存放進程的程序和數據信息,資源清單、進程同步與通信機制。
進程控制塊的組織方式
一、鏈接的方式
將進程按照多個不同的狀態鏈接成多個隊列,如就緒隊列、阻塞隊列、運行隊列等
二、索引的方式
在計算機的內存中,保存一些進程不同狀態的索引表,每個索引表中存儲了各自狀態的進程的地址,然後在內存中存儲這些索引表的首地址。
進程的控制
進程控制的主要作用就是:創建和撤銷進程以及實現進程狀態的轉換。
進程的創建:
1、從進程控制塊PCB集合中申請一塊空白PCB
2、爲新進程分配資源,主要是分配運行必要的內存空間。
3、初始化進程控制塊PCB
4、將新進程插入就緒隊列中
進程的撤銷:
1、從進程控制塊PCB中讀取進程的狀態信息
2、若進程處於運行狀態,設置該進程的調度標誌爲真,表示該進程需要重新調度
3、若該進程還有子進程,終止子進程
4、歸還進程的全部資源
5、將被終止的進程PCB從所在的隊列中移出
進程狀態的轉換:
1、創建態:操作系統爲進程分配了PCB但還未分配其他系統資源就表示該進程處於創建態
2、就緒態:操作系統除了處理機資源其他資源已就緒,表示該進程處於就緒態
3、運行態:操作系統爲就緒態的進程發配了處理機運行時間片,表示該進程處於運行態
4、阻塞態:當操作系統在運行時需要一些資源未被分配或執行一些IO操作被阻塞就表示其在阻塞態
5、終止態:當操作系統遇到錯誤或異常或正常運行結束,操作系統回收其PCB以及其他資源就表示該進程 是終止態
進程與線程:
線程是操作系統運行調度的最小單位,在一個進程內部的多個線程共享通同一進程的資源。爲什麼有了進程還需要有線程呢?由於在有線程之前,進程作爲操作系統分配資源以及調度的基本單位,當進程的狀態進行切換時,開銷大,限制了程序的併發執行。學者的想法是將操作系統分配資源和處理機調度這兩個屬性分開,讓進程擁有計算機資源,只讓線程擁有少量運行必須的資源,這樣子減少了進程的切換。
進程的調度
進程的調度就是操作系統按照一定的策略爲多個進程分配處理機資源。
常見調度算法:
先進先出算法
短處理機有限算法
優先級調度算法
時間片輪轉算法
多級反饋隊列輪轉算法:創建多個不同優先級的就緒隊列,每次分配時間片時,從不同優先級隊列中取出 進程進行分配。
進程的同步與通信
爲什麼需要進程的同步?由於多程序設計,多個運行的進程之間很可能是有聯繫的,表現爲兩種:資源共享關係和相互合作關係。以此有兩個進程同步問題:生產者消費者問題、哲學家進餐問題。
爲了保證多進程併發運行的正確性,需要對多個同時運行的進程進行管理,以協調它們執行的順序或訪問互斥資源的順序。
對於資源共享關係的進程通過進程同步來解決訪問互斥資源問題;相互合作關係的進程通過進程通信來解決進程的順序執行問題。
同步的四個原則:
1、空閒讓進,當互斥資源空閒時,必須允許一個進程訪問。
2、忙則等待,指互斥資源一次只讓一個進程訪問。
3、有限等待,指等待的進程能夠在有限的時間內進入臨界區,避免死等。
4、讓權等待,當進程無法進入臨界區時,應釋放處理機,避免進程陷入忙等。
一些硬件指令可以實現對臨界資源的互斥訪問。
Test-and-Set指令:它是一個操作原語,系統爲每個臨界資源設置全局變量lock並初始化爲0,然後通過當有進程訪問臨界資源時,調用Test-and-Set指令檢測該臨界資源的lock是否爲0並設置爲1,只有執行成功纔可以訪問臨界資源,當進程退出臨界資源時設置變量爲0,下述代碼模仿了Test-and-Set指令。
static int lock = 0;
synchronized int testAndSet(int lock) {
if(lock == 1) {
return lock;
}
int ts = lock;
lock = 1;
return ts;
}
Swap指令:系統爲每個臨界資源設置一個全局變量lock,其初始值爲0。然後每個進程內部都有一個局部變量key,其初始值爲1。然後通過執行指令Swap(lock,key)來判斷lock對應的臨界資源是否可以訪問。Swap指令的語義是:交換lock和key的值,當指令返回值爲1時代表可以訪臨界資源,然後進程退出臨界資源時設置lock=0,key=1。
上面的兩個指令在進程內部調用時,都需要通過一段自旋去不停的訪問全局變量lock的值,因此它無法滿足“讓權等待”原則。
信號量機制:可以理解它是一種特殊的變量,它包括資源數目的整形變量value,一個對應的進程等待隊列,以及對它可以執行的wait()和signal()操作,又稱爲PV操作。剛開始,爲臨界資源創建信號量,設置value初始值,然後進程訪問臨界資源時,調用信號量的wait()操作,它的過程是,判斷value是否小於等於0,如果是則執行失敗,將進程放進等待隊列中,否則將變量value-1表示允許訪問臨界資源,然後進程退出臨界資源時,調用signal()操作,它的過程是將value+1,並從等待隊列中喚醒一個等待的進程執行之前的操作。
管程機制:由於信號量的PV操作必須成對出現,在進程中可能使用錯誤,爲了解決這個問題,Dijkstra提出了祕書進程,即對信號量的操作由祕書進程統一處理,防止誤操作。後來Hansan和Hoare提出了管程的概念。管程是在信號量的基礎上增加了條件變量Condition的概念,Condition表示進程訪問臨界資源被阻塞的原因,與之對應的還有一個等待隊列。舉個例子:緩衝區滿與緩衝區空對應兩個條件變量和兩個等待隊列。
進程通信:進程通信有三種方式:共享存儲、消息傳遞與管道通信。說一下管道通信,它其實是一個連接讀進程和寫進程的共享文件,也被稱爲pipe文件。
死鎖
死鎖是指多個進程互相等待對方持有的臨界區資源且不釋放自己已經持有的資源,導致所有的進程都處於永久等待對方資源的處境。
死鎖產生有四個必要條件:
1、互斥條件,就是資源一次只能被一個進程持有
2、請求和保持條件,對於已持有的資源不會主動放棄
3、不剝奪條件,對於其他進程持有的資源不能強制剝奪
4、環路等待條件,多個進程對於資源
預防死鎖:
1、摒棄“請求保持條件”,已持有資源A,去獲取資源B時失敗,主動釋放資源A,或者一次性獲取所有需要 的資源。
2、摒棄“環路等待條件”,爲所有的資源編號A,B,C,當進程需要獲取資源B時,需要先獲取到資源A,當 想獲取資源C時,需要先獲取資源B,當其中資源B被其他進程持有時,去獲取資源C就會失敗,等其他 進程執行後再執行獲取資源的操作。
避免死鎖: 銀行家算法,所有的資源由銀行統一管理,每次進程獲取資源之前,都需要通過銀行去判斷當 前剩餘資源是否滿足進程所需要的所有資源,如果滿足,則允許進程獲取資源,否則就拒絕進程的要求。有三張表,一張所有進程所需資源表。一張所有進程已申請資源表,還有一張可分配資源表。每次進程申請資源的時候,都通過所需進程表減去已申請資源表,然後比對可分配資源是否滿足進程申請資源的條件,如果滿足則分配給其資源,否則就不分配。
銀行家算法的另一種語義:其實它就是預防死鎖中一次性獲取所有資源的變種,每次進程去獲取資源的時候,都會判斷當前進程是否能夠拿到所需資源,如果能拿到,則分配給它,否則,就把資源分配給其他能完成運行的進程。