操作系统:第二章 进程管理3 - 进程同步与互斥
本文已收錄至 Github(MD-Notes),若博客中有圖片打不開,可以來我的 Github 倉庫:https://github.com/HanquanHq/MD-Notes,涵蓋了互聯(lián)網(wǎng)大廠面試必問的知識點,講解透徹,長期更新中,歡迎一起學(xué)習(xí)探討。
面試必會系列專欄:https://blog.csdn.net/sinat_42483341/category_10300357.html
操作系統(tǒng)系列專欄:https://blog.csdn.net/sinat_42483341/category_10519484.html
第二章 進程管理3 - 進程同步與互斥
目錄
- 第二章 進程管理3 - 進程同步與互斥
- 什么是進程同步
- 進程互斥的原則
- 進程互斥的軟件實現(xiàn)方法
- 1、單標(biāo)志法
- 2、雙標(biāo)志先檢查法
- 3、雙標(biāo)志后檢查法
- 4、Peterson 算法
- 進程互斥的硬件實現(xiàn)方法
- 1、中斷屏蔽方法
- 2、TestAndSetLock 指令
- TSL和中斷屏蔽的區(qū)別
- 利用TSL完成進程間互斥 - 《現(xiàn)代操作系統(tǒng)》P71
- 3、XCHG 指令
- 信號量機制
- 1、整型信號量
- 2、記錄型信號量(默認)
- 記錄型信號量定義
- P 操作(wait 操作)
- V 操作(signal 操作)
- 信號量機制實現(xiàn)進程互斥
- 信號量機制實現(xiàn)進程同步 - 前 V 后 P
- 信號量機制實現(xiàn)前驅(qū)關(guān)系 - 前 V 后 P
- 經(jīng)典的 IPC 問題
- 多生產(chǎn)者 - 多消費者問題
- 分析同步關(guān)系(一前一后):
- 代碼
- 吸煙者問題
- 可以生產(chǎn)多個產(chǎn)品的單生產(chǎn)者問題
- 分析關(guān)系
- 三種組合
- 同步關(guān)系(從事件角度分析)
- 代碼
- 讀者寫者問題
- 代碼
- 哲學(xué)家就餐問題
- 關(guān)系分析
- 如何防止死鎖的發(fā)生呢?
- 代碼
- 管程
- 管程的特征
- 死鎖
- 易混概念辨析
- 死鎖產(chǎn)生的必要條件
- 1、互斥條件
- 2、不剝奪條件
- 3、請求和保持條件
- 4、循環(huán)等待條件
- 什么時候會發(fā)生死鎖
- 1、對系統(tǒng)資源的競爭
- 2、進程推進順序非法
- 2、信號量的使用不當(dāng)
- 死鎖的處理策略
- 1、預(yù)防死鎖
- (1)破壞互斥條件
- 方案
- 缺點:
- (2)破壞不剝奪條件
- 不剝奪條件
- 方案
- 缺點
- (3)破壞請求和保持條件
- 請求和保持條件
- 方案
- 缺點
- (4)破壞循環(huán)等待條件
- 循環(huán)等待條件
- 方案
- 原理
- 缺點:
- 2、避免死鎖
- 銀行家算法
- 銀行家算法的步驟:
- 安全性算法的步驟:
- 安全序列
- 3、死鎖的檢測和解除
- 死鎖檢測思想:
- 死鎖檢測算法:
- 解除死鎖方法:
什么是進程同步
知識點回顧:進程具有異步性的特征。異步性是指,各并發(fā)執(zhí)行的進程以各自獨立的、不可預(yù)知的速度向前推進。
由于并發(fā)必然導(dǎo)致異步性。而實際應(yīng)用中,又必須按照某種順序執(zhí)行,如何解決這種異步問題,就是“進程同步”所討論的內(nèi)容。
同步 亦稱直接 制約關(guān)系,它是指為完成某種任務(wù)而建立的兩個或多個進程,這些進程因為需要在某些位置上 協(xié)調(diào)它們的工作次序 而產(chǎn)生的制約關(guān)系。
對臨界資源的互斥訪問,可以在邏輯上分為如下四個部分:
進程互斥的原則
為了實現(xiàn)對臨界資源的互斥訪問,同時保證系統(tǒng)整體性能,需要遵循以下原則:
進程互斥的軟件實現(xiàn)方法
1、單標(biāo)志法
算法思想:兩個進程在訪問完臨界區(qū)后會把使用臨界區(qū)的權(quán)限轉(zhuǎn)交給另一個進程。也就是說,每個進程進入臨界區(qū)的權(quán)限只能被另一個進程賦予。
turn 的初值為 0,即剛開始只允許 0 號進程進入臨界區(qū)。
該算法可以實現(xiàn)同一時刻最多只允許一個進程訪問臨界區(qū),但是兩個進程必須輪流訪問。如果 P0 一直不訪問臨界區(qū),雖然臨界區(qū)空閑,但并不允許 P1 訪問。違背“空閑讓進”原則。
2、雙標(biāo)志先檢查法
算法思想:設(shè)置一個布爾型數(shù)組flag[],數(shù)組中各個元素用來標(biāo)記各進程想進入臨界區(qū)的意愿,比如“flag[0] = ture”意味著0 號進程P0 現(xiàn)在想要進入臨界區(qū)。每個進程在進入臨界區(qū)之前先檢查當(dāng)前有沒有別的進程想進入臨界區(qū),如果沒有,則把自身對應(yīng)的標(biāo)志flag[i] 設(shè)為true,之后開始訪問臨界區(qū)。
由于進入?yún)^(qū)的“檢查”和“上鎖” 兩個處理不是一氣呵成的,“檢查”后、“上鎖”前 可能發(fā)生進程切換。
主要問題是:**違反“忙則等待”**原則,并發(fā)時可能導(dǎo)致兩個進程同時訪問臨界區(qū)。
3、雙標(biāo)志后檢查法
先“上鎖”后“檢查”的方法,來避免上述問題。
若按照①⑤②⑥的順序執(zhí)行,P0 和 P1 將無法進入臨界區(qū)。
此方法雖然 解決了“忙則等待” 的問題,但是又 違背了“空閑讓進”、“有限等待”原則。
4、Peterson 算法
算法思想:結(jié)合雙標(biāo)志法、單標(biāo)志法的思想。如果雙方都爭著想進入臨界區(qū),那可以讓進程嘗試謙讓
誰最后設(shè)置了 turn 的值,誰就失去了行動的優(yōu)先權(quán)。
Peterson 算法用軟件方法解決了進程互斥問題,遵循了空閑讓進、忙則等待、有限等待三個原則,但是依然未遵循讓權(quán)等待的原則(進程無法獲得使用權(quán)的時候,一直while循環(huán)檢測,消耗CPU資源)。
Peterson 算法相較于之前三種軟件解決方案來說是最好的,但依然不夠好。
進程互斥的硬件實現(xiàn)方法
1、中斷屏蔽方法
與原語的實現(xiàn)思想相同,即在某進程開始訪問臨界區(qū)到結(jié)束訪問為止,都不允許被中斷。
開中斷; 臨界區(qū); 關(guān)中斷;優(yōu)點:
- 簡單,高效
缺點:
- 不適用于多處理機
- 由于開/關(guān)中斷指令是特權(quán)指令,只能運行在內(nèi)核態(tài),因此只適用于內(nèi)核級進程,不適用于用戶級進程
2、TestAndSetLock 指令
TSL 是 Test and Set Lock 的縮寫。要實現(xiàn) TSL 需要硬件的支持。
硬件指令:
TSL RX, LOCK # 測試并加鎖該指令所做的事情:
- 讀取 Lock 的值,存入寄存器RX中
- 給 Lock 設(shè)置一個非0值(設(shè)置到LOCK對應(yīng)的內(nèi)存中)
以上三個步驟是一個 不可拆分 的原子操作,執(zhí)行該指令的CPU將會 鎖住內(nèi)存總線(memory bus),以禁止其他CPU在本指令結(jié)束之前訪問內(nèi)存。
TSL和中斷屏蔽的區(qū)別
當(dāng)一個CPU將中斷屏蔽后,只影響當(dāng)前屏蔽中斷的CPU,其他CPU還是依然可以照樣訪問內(nèi)存的(想要中斷)。唯一一個當(dāng)一個CPU在訪問內(nèi)存時阻止其他CPU訪問內(nèi)存的方法就是將內(nèi)存總線鎖住,這個需要硬件的支持,TSL可以達到該目的。
利用TSL完成進程間互斥 - 《現(xiàn)代操作系統(tǒng)》P71
enter_region:TSL REGISTER, LOCK /*復(fù)制鎖到寄存器并將鎖置1*/CMP REGISTER, #0 /*判斷寄存器內(nèi)容是否為0*/JNE enter_region /*若不是0,說明鎖已經(jīng)被設(shè)置,跳轉(zhuǎn)到enter_region循環(huán)*/RET /*返回調(diào)用者,進入臨界區(qū)*/leave_region:MOVE LOCK, #0 /*在鎖中置0*/RET /*返回調(diào)用者*/(下圖圖源王道)
3、XCHG 指令
一個可替換 TSL 的指令是 XCHG,它原子性地交換了兩個位置的內(nèi)容。它本質(zhì)上與 TSL 的解決方法一樣。
enter_region:MOVE REGISTER, #1 /*給寄存器中置1*/XCHG REGISTER, LOCK /*交換寄存器與鎖變量的內(nèi)容*/CMP REGISTER, #0 /*判斷寄存器內(nèi)容是否為0?*/JNE enter_region /*若不是0跳轉(zhuǎn)到enter_region*/RET /*返回調(diào)用者,進入臨界區(qū)*/ leave_region:MOVE LOCK, #0 /*在鎖中置0*/RET /*返回調(diào)用者*/優(yōu)點:
- 使用硬件方式實現(xiàn)簡單;適用于多處理機環(huán)境
缺點:
- 不滿足“讓權(quán)等待”原則,暫時無法進入臨界區(qū)的進程會占用 CPU 資源并循環(huán)執(zhí)行 TSL 指令,導(dǎo)致忙等
信號量機制
以上所有方案都無法實現(xiàn)讓權(quán)等待,而信號量機制實現(xiàn)了讓權(quán)等待。
用戶進程通過使用操作系統(tǒng)提供的一對原語來對信號量進行操作,實現(xiàn)了進程互斥、進程同步。
-
P 操作:申請 / wait(S) / P(S)
-
V 操作:釋放 / signal(S) / V(S)
1、整型信號量
用一個 整數(shù)型的變量 作為信號量,表示系統(tǒng)中某種資源的數(shù)量。對信號量的三種操作:
- 初始化
- P 操作(將“檢查”和“上鎖”一氣呵成,避免并發(fā) / 異步導(dǎo)致的問題)
- V 操作
存在的問題:不滿足“讓權(quán)等待”原則,會發(fā)生“忙等”,一直 while 占用處理機
2、記錄型信號量(默認)
記錄型信號量定義
S.value 表示系統(tǒng)中某種資源的數(shù)目。
P 操作(wait 操作)
對信號量 S 執(zhí)行一次 P 操作,即執(zhí)行 S.value–,表示資源數(shù)減 1
若 S.value < 0 時,該資源已分配完畢,進程調(diào)用 block 原語自我阻塞(運行態(tài) -> 阻塞態(tài)),主動放棄處理機,并插入該類資源的等待隊列 S.L 中。遵循了“讓權(quán)等待”原則。
V 操作(signal 操作)
對信號量 S 執(zhí)行一次 V 操作,即執(zhí)行 S.value++,表示資源數(shù)加 1
若 S.value <= 0,仍有進程在等待資源,則調(diào)用 wakeup 原語喚醒等待隊列中第一個進程(阻塞態(tài) -> 就緒態(tài))
信號量機制實現(xiàn)進程互斥
信號量機制實現(xiàn)進程同步 - 前 V 后 P
P2 需要這種資源,而只有 P1 才能產(chǎn)生這種資源。即,只有執(zhí)行了 V 操作之后,P 操作之后的代碼才會執(zhí)行。
信號量機制實現(xiàn)前驅(qū)關(guān)系 - 前 V 后 P
進程P1 中有句代碼S1,P2 中有句代碼S2 ,P3中有句代碼S3 …… P6 中有句代碼S6。這些代碼要求按如下前驅(qū)圖所示的順序來執(zhí)行:
其實每一對前驅(qū)關(guān)系都是一個進程同步問題(需要保證一前一后的操作)因此,
經(jīng)典的 IPC 問題
生產(chǎn)者、消費者共享一個初始為空、大小為n的緩沖區(qū)。緩沖區(qū)是臨界資源,各進程必須互斥地訪問。
-
若緩沖區(qū) 不滿,生產(chǎn)者可以 生產(chǎn) -> V(full) 釋放
-
若緩沖區(qū) 非空,消費者可以 消費 -> P(full) 申請
仍然滿足 前 V 后 P:consumer 需要這種資源,而只有 producer 才能產(chǎn)生這種資源。即,只有執(zhí)行了 V(full) 操作之后,P(full) 操作之后的代碼才會執(zhí)行。
semaphore mutex = 1; // 互斥信號量,實現(xiàn)對緩沖區(qū)的互斥訪問 semaphore empty = n; // 同步信號量,表示空閑緩沖區(qū)的數(shù)量 semaphore full = 0; // 同步信號量,表示產(chǎn)品的數(shù)量,也即非空緩沖區(qū)的數(shù)量producer (){ // 生產(chǎn)者while(1){生產(chǎn)一個產(chǎn)品;P(empty); // 實現(xiàn)互斥的 P 操作必須在實現(xiàn)同步的 P 操作之后,否則會導(dǎo)致死鎖P(mutex);把產(chǎn)品放入緩沖區(qū);V(mutex); // 可以改變相鄰 V 操作的順序V(full);} }consumer (){ // 消費者while(1){P(full);P(mutex);從緩沖區(qū)取出一個產(chǎn)品;V(mutex);V(empty);使用產(chǎn)品;} }多生產(chǎn)者 - 多消費者問題
桌上有一盤子,每次只能放入一個水果。爸爸只放蘋果,媽媽只放橘子,兒子只吃橘子,女兒只吃蘋果。
盤子空才能放,盤子有正確的水果才能取。用 PV 操作實現(xiàn)上述過程。
生產(chǎn)者生產(chǎn)的產(chǎn)品、消費者消費的產(chǎn)品類別各不相同。
分析同步關(guān)系(一前一后):
總結(jié):在生產(chǎn)者-消費者問題中,如果緩沖區(qū)大小為1,那么有可能不需要設(shè)置互斥信號量就可以實現(xiàn)互斥訪問緩沖區(qū)的功能。這不是絕對的,要具體問題具體分析。
建議:在考試中如果來不及仔細分析,可以加上互斥信號量,保證各進程一定會互斥地訪問緩沖區(qū)。但需要注意的是,實現(xiàn)互斥的 P 操作一定要在實現(xiàn)同步的 P 操作之后,否則可能引起“死鎖”。
代碼
// semaphore mutex = 1; // 實現(xiàn)互斥訪問盤子(緩沖區(qū)) semaphore apple = 0; // 盤子中有幾個蘋果 semaphore orange = 0; // 盤子中有幾個橘子 semaphore plate = 1; // 盤子中還可以放多少個水果 dad (){while(1){準(zhǔn)備一個蘋果;P(plate); // P 申請盤子里的一個空位把蘋果放入盤子;V(apple); // V 釋放一個蘋果} } mom (){while(1){準(zhǔn)備一個橘子;P(plate);把橘子放入盤子;V(orange);} } daughter (){while(1){P(apple); // P 申請一個蘋果從盤中取出蘋果;V(plate); // V 釋放盤子一個空位吃掉蘋果;} } son(){while(1){P(orange);從盤中取出橘子;V(plate);吃掉橘子;} }吸煙者問題
可以生產(chǎn)多個產(chǎn)品的單生產(chǎn)者問題
系統(tǒng)中有 三個抽煙者進程,每個抽煙者不斷地卷煙并抽煙。抽煙者卷起并抽掉一顆煙需要有三種材料:煙草、紙、膠水。一個抽煙者有煙草,一個有紙,另一個有膠水。
系統(tǒng)中還有 一個供應(yīng)者進程,它們無限地供應(yīng)所有三種材料,但每次僅輪流提供三種材料中的兩種。
得到缺失的兩種材料的抽煙者在卷起并抽掉一顆煙后,會發(fā)信號通知供應(yīng)者,讓它繼續(xù)提供另外的兩種材料。這一過程重復(fù)進行。
請用以上介紹的 IPC 同步機制編程,實現(xiàn)該問題要求的功能。
分析關(guān)系
桌子:容量為1的緩沖區(qū),要互斥訪問
三種組合
同步關(guān)系(從事件角度分析)
發(fā)出完成信號 -> 供應(yīng)者將下一個組合放到桌上
代碼
不需要設(shè)置一個專門的同步信號量。因為緩沖區(qū)大小為 1,故同一時刻,四個同步信號量中至多有一個為 1。
semaphore offer1 = 0; // 桌上組合一的數(shù)量 semaphore offer2 = 0; // 桌上組合二的數(shù)量 semaphore offer3 = 0; // 桌上組合三的數(shù)量 semaphore finish = 0; // 抽煙是否完成 int i = 0; // 用于實現(xiàn)“三個抽煙者輪流流抽煙”provider (){while(1){if(i==0) {將組合一放桌上;V(offer1);} else if(i==1){將組合二放桌上;V(offer2);} else if(i==2){將組合三放桌上;V(offer3);}i = (i+1)%3;P(finish);} }smoker1 (){while(1){P(offer1);從桌上拿走組合一;卷煙;抽掉;V(finish);} }smoker2 (){while(1){P(offer2);從桌上拿走組合二;卷煙;抽掉;V(finish);} }smoker3 (){while(1){P(offer3);從桌上拿走組合三;卷煙;抽掉;V(finish);} }讀者寫者問題
有讀者、寫者兩組并發(fā)進程,共享一個文件。規(guī)則:
- 允許 多個讀者 同時 讀 文件
- 只允許 一個寫者 寫文件
- 寫完成 之前 不允許讀
- 讀完成 之前 不允許寫
互斥關(guān)系
-
互斥:寫 - 寫 / 寫 - 讀
-
不互斥:讀 - 讀
代碼
讀寫公平法:即使連續(xù)有 多個讀者 到來,也 不會使寫者一直饑餓,是相對公平的先來連服務(wù)原則。
semaphore rw = 1; // 讀寫信號量,實現(xiàn)只讀或只寫(互斥訪問) int count = 0; // 記錄當(dāng)前有幾個讀者程在訪問文件 semaphore mutex = 1; // 用于保證對count變量的互斥訪問 semaphore w = 1; // 用于保證寫者不會饑餓writer (){ // 寫者while(1){P(w); // 用于保證寫者不會饑餓P(rw); // 寫者申請一個讀寫信號量(意味著只寫)寫文件;V(rw);V(w);} }reader (){ // 讀者while(1){P(w); // 用于保證寫者不會饑餓P(mutex); // 對count操作前,需要申請count變量的獨占if(count == 0){ // 沒有讀者P(rw); // 讀者申請一個讀寫信號量(意味著只讀)}count++; // 全局變量增加一個寫進程V(mutex); // 釋放count變量的獨占V(w);讀文件;P(mutex);count--;if(count == 0){V(rw);}V(mutex);} }哲學(xué)家就餐問題
圓桌坐著 5 名哲學(xué)家,每兩個哲學(xué)家之間有一根筷子,哲學(xué)家交替進行思考和進餐。進餐時,試圖一根一根拿起左、右兩根筷子,只有同時拿起兩根筷子才能進餐,否則需要等待。進餐完畢后,哲學(xué)家放下筷子繼續(xù)思考。
關(guān)系分析
- 5 個哲學(xué)家進程
- 相鄰哲學(xué)家對中間筷子的訪問是互斥關(guān)系
每個哲學(xué)家進程需要同時持有兩個臨界資源才能開始吃飯。如何避免死鎖現(xiàn)象,才是哲學(xué)家問題的精髓。
定義互斥信號量數(shù)組 chopstick[5] = {1, 1, 1, 1, 1} 用于實現(xiàn)對 5 個筷子的互斥訪問。并對哲學(xué)家按 0 ~ 4 編號,哲學(xué)家 i 左邊的筷子編號為 i,右邊的筷子編號為 (i + 1) % 5
如何防止死鎖的發(fā)生呢?
有很多種方式,舉幾個例子:
代碼
思想:使用 mutex 來實現(xiàn) 只允許一個哲學(xué)家 處于 只拿起了一只筷子的狀態(tài)
semaphore chopstick[5]={1,1,1,1,1}; semaphore mutex = 1; // 互斥地取筷子 Pi (){ // i 號哲學(xué)家的進程while(1){P(mutex);P(chopstick[i]); // 拿左P(chopstick[(i+1)%5]); // 拿右V(mutex);吃飯;V(chopstick[i]); // 放左V(chopstick[(i+1)%5]); // 放右思考;} }管程
《現(xiàn)代操作系統(tǒng)》P79
由于使用信號量時要非常小心,而且出現(xiàn)的錯誤都是競爭條件、死鎖以及其它一些不可預(yù)測或不可再現(xiàn)的行為,而為了更易于編寫正確的程序,提出了一種高級同步原語,稱為管程(monitor)
一個 管程 是由一個過程、變量及數(shù)據(jù)結(jié)構(gòu)等組成的一個集合,它們組成一個 特殊的模塊 或 軟件包。
管程有一個很重要的特性:任一時刻,管程中只能有一個活躍進程。
管程是編程語言的組成部分,編譯器知道它們的特殊性,因此可以采用與其它過程調(diào)用不同的方法來處理對管程的調(diào)用。由編譯器而非程序員來安排互斥,出錯的可能性要小很多。
-
Java 的 syncronized 就是一個管程,也可使用 wait() / notify() 實現(xiàn)進程的同步。
-
C,Pascal 以及多數(shù)其他語言都沒有管程。
管程的特征
死鎖
易混概念辨析
死鎖:各進程互相等待對方手里的資源,導(dǎo)致各進程都阻塞,無法向前推進(操作系統(tǒng)考慮)
饑餓:由于長期得不到想要的資源,某進程無法向前推進(操作系統(tǒng)考慮)
死循環(huán):某進程執(zhí)行過程中一直跳不出某個循環(huán),是可以上處理機運行的(開發(fā)人員考慮)
死鎖產(chǎn)生的必要條件
1、互斥條件
只有對必須互斥使用的資源的爭搶才會導(dǎo)致死鎖(如哲學(xué)家的筷子、打印機設(shè)備)。像內(nèi)存、揚聲器這樣可以同時讓多個進程使用的資源是不會導(dǎo)致死鎖的(因為進程不用阻塞等待這種資源)。
2、不剝奪條件
進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放。
3、請求和保持條件
進程已經(jīng)保持了至少一個資源,但又提出了新的資源請求,而該資源又被其他進程占有,此時請求進程被阻塞,但又對自己已有的資源保持不放。
4、循環(huán)等待條件
存在一種進程資源的循環(huán)等待鏈,鏈中的每一個進程已獲得的資源同時被下一個進程所請求。
什么時候會發(fā)生死鎖
1、對系統(tǒng)資源的競爭
各進程對不可剝奪的資源(如打印機)的競爭可能引起死鎖,對可剝奪的資源(CPU)的競爭是不會引起死鎖的。
2、進程推進順序非法
請求和釋放資源的順序不當(dāng),也同樣會導(dǎo)致死鎖。例如,并發(fā)執(zhí)行的進程P1、P2 分別申請并占有R1、R2,之后進程P1申請R2,進程P2申請R1,兩者因為申請的資源被對方占有而阻塞,發(fā)生死鎖。
2、信號量的使用不當(dāng)
如生產(chǎn)者-消費者問題中,如果實現(xiàn)互斥的P操作在實現(xiàn)同步的P操作之前,就有可能導(dǎo)致死鎖。(可以把互斥信號量、同步信號量也看做是一種抽象的系統(tǒng)資源)
死鎖的處理策略
1、預(yù)防死鎖
破壞死鎖產(chǎn)生的四個必要條件中的一個或幾個。
(1)破壞互斥條件
方案
把只能互斥使用的資源改造為允許共享使用,則系統(tǒng)不會進入死鎖狀態(tài)。比如,操作系統(tǒng)可以采用 SPOOLing 技術(shù)把獨占設(shè)備在邏輯上改造成共享設(shè)備。
缺點:
并不是所有的資源都可以改造成可共享使用的資源。很多時候無法破壞互斥條件。
(2)破壞不剝奪條件
不剝奪條件
進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放。
方案
- 方案一:當(dāng)某個進程請求新的資源得不到滿足時,它必須立即釋放保持的所有資源,待以后需要時再重新申請。也就是說,即使某些資源尚未使用完,也需要主動釋放,從而破壞了不可剝奪條件。
- 方案二:當(dāng)某個進程需要的資源被其他進程所占有的時候,可以由操作系統(tǒng)協(xié)助,將想要的資源強行剝奪。這種方式一般需要考慮各進程的優(yōu)先級(比如:剝奪調(diào)度方式,就是將處理機資源強行剝奪給優(yōu)先級更高的進程使用)
缺點
(3)破壞請求和保持條件
請求和保持條件
進程已經(jīng)保持了至少一個資源,但又提出了新的資源請求,而該資源又被其他進程占有,此時請求進程被阻塞,但又對自己已有的資源保持不放。
方案
采用 靜態(tài)分配 方法,進程在運行前,一次申請完它需要的全部資源才能投入運行。一旦投入運行,一直保持資源,且不再請求別的任何資源,直到運行結(jié)束,釋放資源。
缺點
(4)破壞循環(huán)等待條件
循環(huán)等待條件
存在一種進程資源的循環(huán)等待鏈,鏈中的每一個進程已獲得的資源同時被下一個進程所請求。
方案
順序資源分配法。首先給系統(tǒng)中的資源編號,規(guī)定每個進程必須按編號遞增的順序請求資源,同類資源(即編號相同的資源)一次申請完。
原理
一個進程只有已占有小編號的資源時,才有資格申請更大編號的資源。
- 任一時刻,總有一進程擁有的資源編號是最大的,此進程對其余資源的獲取必暢通無阻
- 已持有大編號資源的進程不可能逆向地回來申請小編號的資源,從而就不會產(chǎn)生循環(huán)等待的現(xiàn)象
缺點:
2、避免死鎖
用某種方法防止系統(tǒng)進入不安全狀態(tài),從而避免死鎖(銀行家算法)
銀行家算法
一個小城鎮(zhèn)的銀行家向一群客戶分別承諾了一定的貸款額度,只有當(dāng)借款總數(shù)達到客戶最大要求時,客戶才歸還貸款,否則無論之前借了多少錢,都拿不回來。
銀行家算法的步驟:
安全性算法的步驟:
安全序列
所謂的安全序列,就是指系統(tǒng)如果按照這種序列分配資源,則每個進程都能順利完成。只要能找出一個安全序列,系統(tǒng)就處于安全狀態(tài)。當(dāng)然,安全序列可以有多個。
一個 找不到 安全序列的例子:(剩余資源總數(shù) 3 3 2)可以拓展到有 n 個進程,m 種資源
| P0 | 8 5 3 | 0 1 0 | 8 4 3 |
| P1 | 3 2 2 | 2 0 0 | 1 2 2 |
| P2 | 9 5 2 | 3 0 2 | 6 5 0 |
| P3 | 2 2 2 | 2 1 1 | 0 1 1 |
| P4 | 4 3 6 | 0 0 2 | 4 3 4 |
3、死鎖的檢測和解除
允許死鎖的發(fā)生,不過操作系統(tǒng)會負責(zé)檢測出死鎖的發(fā)生,然后采取某種措施解除死鎖。
- 死鎖檢測算法:用于檢測系統(tǒng)狀態(tài),以確定系統(tǒng)中是否發(fā)生了死鎖。
- 死鎖解除算法:當(dāng)認定系統(tǒng)中已經(jīng)發(fā)生了死鎖,利用該算法可將系統(tǒng)從死鎖狀態(tài)中解脫出來。
死鎖檢測思想:
依次消除與不阻塞進程相連的邊,直到無邊可消。
-
如果最終 能消除所有邊,就稱這個圖是可完全簡化的。此時一定沒有發(fā)生死鎖(即找到一個 安全序列)
-
如果最終 不能消除所有邊,那么此時就是 發(fā)生了死鎖。剩余連著邊的進程,就是處于死鎖狀態(tài)的進程。
死鎖檢測算法:
解除死鎖方法:
總結(jié)
以上是生活随笔為你收集整理的操作系统:第二章 进程管理3 - 进程同步与互斥的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统:第二章 进程管理2 - 处理机
- 下一篇: 操作系统:第三章 内存管理2 - 详解虚