第二章、進程的描述與控制
2.1 前趨圖和程序執行
2.1.1 前趨圖
概念:
所謂前趨圖:指一個有向無循環圖(DAG),它用於描述進程之間執行的先后順序。
2.1.2 程序順序執行
特征:
- 順序性
- 封閉性:指程序在封閉的環境中運行,程序運行時獨占全機資源,資源的狀態只有本程序才能改變,程序一旦開始執行,其執行結果不受外界因素影響
- 可再現性:只要條件相同還會得到相同的執行結果。
2.1.3 程序並發執行
特征:
- 間斷性
- 失去封閉性
- 不可在現性
2.2進程的描述
2.2.1 進程的定義和特征
定義
為了使程序並發執行,並且可以對並發執行的程序加以描述和控制,人們引入了進程的概念。
為了使參與並發執行的每個程序都能獨立運行,在操作系統中必須為之分配一個專門的數據結構,稱為進程控制塊(PCB)。系統利用PCB來描述進程的基本情況和活動過程,進而控制和管理進程。
因此進程的定義為:由程序段、相關的數據段和PCB三部分構成的進程實體。
比較典型的定義有:
- 進程是程序的一次執行
- 進程是一個程序及其數據在處理機上順序執行時所發生的活動
- 進程是具有獨立功能的程序在一個數據結合上運行的過程,它是系統進行資源分配和調度的一個獨立單位。
進程的特征
- 動態性
- 並發性
- 獨立性
- 異步性
2.2.2 進程的基本狀態以及轉換
進程三種基本狀態
由於多個進程在並發執行時共享系統資源,致使他們在運行過程中呈現間斷性的運行規律,所以進程在生命周期內可能具有不同狀態。一般而言,每個進程至少應處於以下三種基本狀態:
- 就緒(Ready)狀態
指進程已處於准備好運行的狀態,即進程已分配到除CPU以外的所有必要資源后,只要再獲得CPU就可以立即執行。如果有多個就緒狀態的進程。
通常按照一定的策略排成一個隊列,稱該隊列為就緒隊列 - 執行(Running)狀態
指進程已經獲得CPU,其程序正在執行的狀態。在單處理機系統中,只有一個進程處於執行狀態,而多處理機系統則有多個進程處於執行狀態。 - 阻塞(Block)狀態
指正在執行的進程由於發生某事件(如I/O請求、申請緩沖區失敗等)暫時無法繼續執行時的狀態,即進程的執行受到了阻塞。此時引起進程調度,OS把處理機分配給另一個就緒的進程,而讓受阻進程處於暫停狀態,一般將這種暫停狀態稱為阻塞狀態,有時也稱為等待狀態或封鎖狀態。
通常系統將處於阻塞狀態的進程也排成一個隊列,稱為阻塞隊列。
三種基本狀態的轉換
- 就緒--->執行 處於就緒狀態的進程,在調度程序為之分配了處理機之后便可執行 。
- 執行--->就緒 正在執行的進程如果因為分配給他的時間片用完而被剝奪處理機暫停執行,其狀態就會變成就緒。
- 執行--->阻塞 如果因發生某事件,致使當前進程行為受阻(例如進程訪問臨界資源,而該資源正被其他進程訪問時),則變成了阻塞。
創建狀態和終止狀態
創建狀態
申請PCB,填寫用於控制和管理進程的信息--->分配必須資源--->把進程轉入就緒狀態並插入就緒隊列。
引入創建狀態是為了保證進程調度必須在創建工作完成后進行,以確保對進程控制塊操作的完整性。
終止狀態
兩個步驟: 首先,是等待操作系統進行善后處理,最后將其PCB清零,並將PCB空間返還系統。
2.2.3 掛起操作和進程狀態的轉換
當掛起操作作用與某個進程時,該進程被掛起,意味着此時該進程處於靜止狀態。如果進程在執行,那么將暫停執行。
引入掛起的原因
- 終端用戶的需要
- 父進程的請求
- 負荷調節的需要
- 操作系統的需要
引入掛起原語操作后三個進程的狀態轉換
引入掛起原語Suspend和激活原語Active后,進程可能發生以下幾種狀態轉換:
- 活動就緒--->靜止就緒
當進程處於未被掛起的就緒狀態時,被稱為活動就緒狀態,標示為Readya,此時進程接受調度。當用Suspend將進程掛起時,此進程變為靜止就緒狀態,表示為Readys,此時進程不再被調度執行。 - 活動阻塞--->靜止阻塞
當進程未被掛起時的阻塞狀態稱為活動阻塞狀態,表示為Blockda,當用SUspend掛起時,便成為了靜止阻塞,表示為Blockeds.處於該狀態的進程中在其所期待的事件出現后,它將從靜止阻塞變為靜止就緒狀態Readys狀態。 - 靜止就緒--->活動就緒
處於Readys狀態的進程若用Active激活后,就變成了活動就緒Readya狀態。 - 靜止阻塞--->活動阻塞
處於Blockeds狀態的用Active激活后,變成Blockeda狀態。
2.2.4 進程管理中的數據結構
進程控制塊的作用
進程控制塊的作用是使一個在多道程序環境下不能獨立運行的程序成為一個能獨立運行的基本單位,一個能與其他進程並發執行的進程。
- 作為獨立運行基本單位的標志。
- 能實現間斷性運行方式。
- 提供進程管理所需要的信息。
- 提供進程調度所需要的信息。
- 實現與其他進程的同步與通信。
2.3 進程控制
2.3.1 引起創建進程的事件
- 用戶登錄
- 作業調度
- 提供服務
- 應用請求
2.3.2 進程創建步驟:
- 申請空白PCB,為新進程申請獲得唯一的數字標識符,並從PCB集合中索取一個空白PCB。
- 為新進程分配其運行所需要的資源,包括物理和邏輯資源,如內存、文件、I/O設備和CPU時間等。
- 初始化進程控制塊
- 如果進程就緒隊列能夠接納新的進程,便將新進程插入就緒隊列。
2.3.3 進程的終止
引起進程終止的事件:
- 正常結束,表示進程的任務已經完成,准備推出運行。
- 異常結束,指進程在運行時發生了某種異常事件,使程序無法繼續運行。
- 越界錯:程序訪問存儲區超出該進程區域
- 保護措:進程訪問一個不允許訪問的資源,或者以不當的方式訪問。
- 非法指令:程序試圖去執行不存在的指令
- 特權指令錯:用戶進程試圖去執行一條只允許OS執行的指令
- 運行超時:進程執行事件超過了制定的最大值
- 等待超時:進程等待的時間超過了規定最大值
- 算術運算錯:進程試圖執行一個被禁止的運算。例如被0除。
- I/O故障:I/O過程中發生錯誤。
- 外界干預
- 操作員或者操作系統干預
- 父進程請求
- 父進程終止
進程終止的過程
- 根據被終止進程的標識符,從PCB集合中檢索出該進程的PCB,從中讀取該進程的狀態
- 若被終止進程正在處於執行狀態,則立即終止執行,並置調度標志為真,用於指示該進程被終止后應重新進行調度。
- 如有該進程有子進程,則所有子進程也終止
- 將被終止進程PCB從隊列移除,等待其他程序來搜集信息。
2.3.4 進程的阻塞與喚醒
引起進程阻塞和喚醒的事件:
- 向系統請求共享資源失敗
請求共享資源,但是沒有足夠資源分配,所以進程變為阻塞狀態。 - 等待某種操作的完成
例如一個進程的完成必須要有另一個進程的支持,即另個進程完成后這個進程才能執行,這時候進程變為阻塞狀態。 - 新數據尚未到達
- 等待新任務到達
進程阻塞過程
如果進程執行,則立刻停止,把PCB插入阻塞隊列。
進程喚醒過程
當阻塞進程所期待的事件發生,則調用喚醒原語wakeup,從阻塞隊列移出,將PCB狀態由阻塞變為就緒,然后把PCB插入就緒隊列中。
2.3.5 進程的掛起與激活
進程的掛起
檢查進程狀態,如果活動就緒改為靜止就緒;如果活動阻塞改為靜止阻塞。為了方便用戶或父進程考察該進程的運行情況,把進程PCB復制到制定內存區域;最后若被掛起的進程正在執行,則扎ungxiangdiaodu程序重新調度。
進程的激活狀態
利用激活原語Active,把進程從外存調入內存,檢查其狀態,若靜止就緒改為活動就緒;若靜止阻塞改為活動阻塞。
2.4 進程同步
2.4.1 進程同步的基本概念
進程同步機制的主要任務,是對多個相關進程在執行次序上進行協調,使並發執行的進程之間能夠按照一定的規則共享系統資源,並且很好地相互合作,從而使程序的執行具有可再現性。
兩種形式的制約關系
由於共享資源或者為完成某一任務相互合作,而產生制約關系
- 間接相互制約關系
多個程序在並發執行時,由於共享系統資源導致這些並發執行程序之間形成的相互制約關系。例如打印機這些臨界資源 - 直接相互制約關系
通過合作而產生的制約關系。例如只有a執行過后,b才能執行。而兩者都是為了完成某一個功能。
臨界資源
只能一個進程訪問的資源。進程之間采取互斥方式,實現對這種資源的共享。通過生產者---消費者問題(進程同步問題)可說明這一過程。 (具體不再說明該問題) 。
臨界區
每個進程中訪問臨界資源的那段代碼稱為臨界區。可把一個訪問臨界資源的循環進程描述如下:
while(TRUE)
{
進入區
臨界區
退出區
剩余區
}
同步機制應遵循的規則
- 空閑讓進
- 忙則等待
- 有限等待
- 讓權等待:當進程不能進入自己的臨界區時,應立即釋放處理機,以免進程陷入忙等狀態。
2.4.2 硬件同步機制
再次不再介紹
2.4.3 信號量機制
整型信號量
記錄型信號量
AND型信號量
信號量集
2.5 進程通信
進程通信是指進程之間的信息交換。
- 低級通信和高級通信
- 低級通信:效率低:生產者只能向緩沖池投一個產品,消費者只能取一個;通信對用戶不透明
- 高級通信:使用方便;高效傳送大量數據。
2.5.1 進程通信的類型
高級通信機制可歸為以下四大類:
- 共享存儲器系統。
存在一塊共享某些數據結構或者共享存儲區,通過這些空間進行通信。又分為: - 基於共享數據結構的通信方式(低級通信)
- 基於共享存儲區的通信方式(高級通信)
- 管道通信系統
- 消費傳遞系統
- 客戶機-服務器系統
2.5.2 消息傳遞通信的實現方式
- 直接消息傳遞系統
- 信箱通信
2.5.3 進程通信的幾種方式(管兩信,報共套)
* 管道(pipe)以及有名管道(named pipe) 管道可用於具有親緣關系的進程之間的通信,有名管道克服了管道沒有名字的限制。因此,除具有管道所有具有的功能外,它還允許無親緣關系的進程通信 * 信號(Signal) 信號是比較負載的通信方式,用於通知接收進程有某種事件發生,除了用於進程通信外,進程還可以發送信號給進程本身。 * 報文(Message)隊列(消息隊列) 消息隊列是消息的鏈接表。有足夠權限的進程可以想隊列添加消息,被賦予讀權限的進程可以讀走隊列中的消息。 * 共享內存 是多個進程可以訪問同一塊內存,是最快的IPC形式。 * 信號量(samaphore) 主要作為進程之間以及統一進程不同線程之間的同步手段。 * 套接口(Socket) 更為一般的進程間通信機制,可以用於不同機器之間進程間的通信 ##2.6 線程(Threads)的基本概念 ###線程的引入 如果說在OS中引入進程的目的是為了使多個程序能夠並發執行,以提高資源利用率和系統吞吐量,那么,在操作系統中再引入線程,則是為了減少程序在並發執行時所付出的時空開銷,使OS具有更好的並發性。 #####進程的兩個基本屬性 * 進程是一個可擁有資源的獨立單位,一個基礎南橫要能獨立運行它必須擁有一定的資源。 * 進程同時又是一個可獨立調度和分派的基本單位。程序並發執行所需付出的時空開銷
由於進程是一個資源擁有者,因而在創建、撤銷和切換中,系統必須為之付出較大的時空開銷。
線程是調度和分派的基本單位。
線程與進程的比較
線程具有許多傳統進程所具有的特征,所以又稱為輕型進程或進程元。相應地把傳統進程稱為重型進程。它相當於有一個線程的任務。
- 調度的基本單位
傳統的OS中,進程是作為獨立調度和分派的基本單位,在每次調用時,都需要上下文切換,開銷較大。
而引入線程的OS中,已把線程作為調度和分派的基本單位。當線程切換時,只需保存和設置少量寄存器的內容,切換代價低於進程。在同一個進程中,線程的切換不會引起進程的切換,但從一個進程中的線程切換到另一個進程中的線程時,必然會引起進程的切換。 - 並發性
線程的並發性比較好。一個進程中的多個線程之間亦可並發執行;一個進程中的所有線程都可以並發執行;不同進程中的線程也能並發執行。如果采用傳統的進程,則每次只能執行一個任務,並發性不太好。 - 擁有資源
進程可以擁有資源,而線程本身不擁有系統資源,而是僅有一點必不可少的、能保證獨立運行的資源。而且線程還允許多個線程共享該進程所擁有的資源。 - 獨立性
同一進程中不同線程之間獨立性比不同進程之間獨立性低得多。 - 系統開銷
創建或者撤銷進程是系統開銷比線程要大。 - 支持多處理機系統
對於傳統進程,即單線程進程,不管有多少個處理機,該進程只能運行在一個處理機上。但是對於多線程進程,可以將一個進程中的多個線程分配到多個處理機,提高進程完成速度。
總的來說:可以用占有資源的多少,並發性,獨立性和支持多處理機系統方面來概述。
線程的狀態和線程控制塊
線程狀態
執行、就緒、阻塞。和進程一樣
線程控制塊(TCB)
- 線程標識符
- 一組寄存器
- 線程運行狀態
- 優先級
- 線程專有存儲區
- 信號屏蔽
- 堆棧指針
2.7 線程的實現
線程的實現方式
-
內核支持線程KST (Kernel Supported Thread)
執行、創建、撤銷和切換都是在內核空間中實現的。調度以線程為單位進行。有以下優點:- 在多處理器系統中,內核能夠同時調用同一進程中的多個線程並執行
- 如果進程中的一個線程阻塞,那么內核可以調度其他線程占有處理器運行。
- 內核支持的線程具有很小的數據結構和堆棧,線程切換比較快,切換開銷小。
- 內核本身也可以采用多線程技術,可以提高系統的執行速度和效率。
其缺點是: 對於用戶線程切換而言,其模式切換的開銷較大,在同一個進程中,從一個線程切換到另一個線程時,需要從用戶態轉到核心態進行,這是因為用戶進程的線程在用戶態運行,而線程調度和管理在內核實現,系統開銷較大。
-
用戶級線程ULT(User Level Threads)
用戶級線程是在用戶空間中實現的。對線程的創建、撤銷、同步與通信等功能,都無需內核支持,即用戶級線程與內核無關。調度仍是以進程為單位進行。用戶級線程的優點: -
線程切換不需要轉換到內核空間
-
調度算法可以是進程專用的
-
用戶線程的實現與OS平台無關。