操作系統3——進程的描述與控制
——2018.12.10
文章目錄
零、目標
- 進程的定義和特徵
- 進程的基本狀態及轉換
- 進程控制塊
- 內核、原語
- 臨界資源、臨界區
- 同步機制應遵循的規則
- 記錄型信號量、利用記錄型信號量解決生產者
一、進程的描述
1. 進程的概念
- 進程的定義:是進程實體的運行過程,是系統進行資源分配和調度的一個獨立單位。
- 進程的特徵:動態性、併發性、獨立性、異步性
- PCB 描述和控制進程運行,系統爲每個進程定義的一個數據結構
- 程序的代碼和數據、CPU寄存器的數值、堆和棧
- 系統資源
- 地址空間
- 打開的文件
2.進程的狀態
- 就緒(Ready)狀態
- 可運行,已獲得除CUP外的所需資源,等待分配CPU
- 執行(Running)狀態
- 佔用CPU運行,處於此狀態的進程數目=CPU的數目
- 阻塞(Blocked)狀態
- 等待某種條件(如I/O)操作或進程同步,在滿足條件前無法執行
3.進程的管理
- 引起進程創建的原因:
- 用戶登錄:爲終端用戶建立進程
- 作業調度:選中的作業建立進程
- 提供服務:爲用戶提供的服務進程
- 應用請求:應用程序自己創建的進程
- 原語:由若干條指令構成,用於完成一定功能的一個過程
- 原子操作:一個操作中的所有動作,要麼全做,要麼全不做,是一個不可分割的操作。
- 進程控制塊的組織方式
- 鏈接方式:把具有同一狀態的PCB,用其中的鏈接字鏈接成一個隊列
- 索引方式:系統根據所有進程的狀態建立幾張索引表
二、線程的描述
1.線程的概念
- 線程的定義:
- 將進程的兩個屬性分開,作爲調度和分派的基本單位,不同時作爲資源的擁有者,就形成了線程的概念
- 線程:有時稱輕量級進程,進程中的一個運行實體,是一個CPU調度單位,資源的擁有者還是進程或稱任務
- 一個被調度和分派的基本單位並可獨立運行的實體
- 線程的分類
- 內核支持線程:依賴內核進行控制和管理
- 用戶級線程:在用戶級創建、撤銷和切換
- 在引入線程的OS系統中,則把線程作爲調度和分派的基本單位,而把進程作爲資源的擁有基本單位。
- 在同一進程中的線程切換不會引起進程切換
- 在不同一進程中的線程切換會引起進程切換
三、進程同步
1.相關的概念
- 互斥——間接相互制約關係
- 同處於一個系統中的進程必然共享某種資源,如CPU、I/O設備等,間接相互制約即源於共享資源
- 同步——直接相互制約關係
- 源於進程進程之間的合作關係,如進程A向B提供數據,當輸入緩衝空時,B不能得到數據而阻塞
- 臨界資源
- 一次僅允許一個進程使用的資源
- 系統中的許多硬件,如打印機,諸進程之間只能用互斥的方式進行訪問
- 臨界區
- 在每個進程中訪問臨界資源的那段代碼稱爲臨界區
2.同步機制應遵循的原則
- 空閒讓進
- 當無進程處於臨界區時,應允許一個進程進入臨界區
- 忙則等待
- 當已有進程進入臨界區時,其他進程必須等待
- 有限等待
- 應保證在有限時間內進入自己的臨界區,防止“死等”
- 讓權等待
- 應立即釋放處理機,防止“忙等”
3.互斥與同步的解決方法:
- 軟件方法
- 由進程通過執行相應的程序指令,實現與其他進程的互斥與同步
- 硬件方法
- 通過屏蔽中斷(單CPU)或是採用專門的機器指令控制互斥與同步
- 信號量方法
- 經典信號量——表示資源的物理實體
- 記錄型信號量——更有效地利用資源,解決忙等的問題
typedef struct{
int value;
struct process_control_block *list;
}semaphore;
wait(semaphore *S){
S->value--;//請求一個該類資源
if(S->value<0) block(S->list);//該類資源已分配完畢,調用block原語進行自我阻塞並放棄處理機、插入到信號量列表S->list中
}
signal(semaphore *S){
S->value++;//釋放一個資源
if(S->value<=0) wakeup(S->list);//有進程被阻塞
}
- AND型信號量機制——防止系統出現不安全性
- 管程方法
- 管程:⼀個管程定義了⼀個數據結構和能爲併發進程所執⾏的⼀組操作,這組操作能同步進程和改變管程中的數據
四、經典進程的同步問題
1 .利用記錄型信號量解決生產者-消費者問題
問題描述:
有一羣生產者進程在生產產品,並將這些產品提供給消費者進程去消費。爲使生產者進程與消費者進程能併發執行,在兩者之間設置了- -個具有n個緩衝區的緩衝池,生產者進程將它所生產的產品放入一個緩衝區中;消費者進程可從一個緩衝區中取走產品去消費。
int in = 0, out = 0;//in: 輸入指針, out: 輸出指針;
item buffer[n];//n個緩衝區組成的數組;
semaphore mutex = 1, full = 0, empty = n;
//mutex: 互斥信號量, 生產者進程和消費者進程都只能互斥訪問緩衝區;
//full: 資源信號量, 滿緩衝區的數量;
//empty: 資源信號量, 空緩衝區的數量;//信號量不允許直接參與運算, 故都要定義;
//生產者程序;
void producer() {
do {
producer an item nextp;//生產者生產一個產品
...
wait(empty);//申請一個空緩衝區;
wait(mutex);//申請臨界資源;
buffer[in] = nextp;//將產品添加到緩衝區;
in = (in + 1) % n;//類似於循環隊列;
signal(mutex);//釋放臨界資源;
signal(full);//釋放一個滿緩衝區;
} while (TRUE);
}
//消費者程序;
void consumer() {
do {
wait(full);//申請一個滿緩衝區;
wait(mutex);//申請臨界資源;
nextc = buffer[out];//將產品從緩衝區取出;
out = (out + 1) % n;//類似於循環隊列;
signal(mutex);//釋放臨界資源;
signal(empty);//釋放一個空緩衝區;
consumer the item in nextc//消費者將一個產品nextc消費;
} while (TRUE);
}
void main(){
cobegin
producer(); consumer();
coend
}