日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

操作系统:第二章 进程管理3 - 进程同步与互斥

發(fā)布時間:2024/2/28 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统:第二章 进程管理3 - 进程同步与互斥 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文已收錄至 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)整體性能,需要遵循以下原則:

  • 空閑讓進。臨界區(qū)空閑時,可以允許一個請求進入臨界區(qū)的進程立即進入臨界區(qū);
  • 忙則等待。當(dāng)已有進程進入臨界區(qū)時,其他試圖進入臨界區(qū)的進程必須等待;
  • 有限等待。對請求訪問的進程,應(yīng)保證能在有限時間內(nèi)進入臨界區(qū)(保證不會饑餓);
  • 讓權(quán)等待。當(dāng)進程不能進入臨界區(qū)時,應(yī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)用者*/
  • 如果LOCK的值為0,則將LOCK的值設(shè)置為1,且進入臨界區(qū)
  • 如果LOCK的值為1,則一直循環(huán)等待
  • 如果多個進程同時調(diào)用TSL,利用TSL的特性:只有一個進程訪問,其他的會被block
  • (下圖圖源王道)

    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)進程互斥

  • 分析并發(fā)進程的關(guān)鍵活動,劃定臨界區(qū)(如:對臨界資源打印機的訪問就應(yīng)放在臨界區(qū))
  • 設(shè)置互斥信號量 mutex,初值為 1
  • 在進入?yún)^(qū) P(mutex)——申請資源
  • 在退出區(qū) V(mutex)——釋放資源
  • 信號量機制實現(xiàn)進程同步 - 前 V 后 P

  • 分析什么地方需要實現(xiàn)“同步關(guān)系”,即必須保證“一前一后”執(zhí)行的兩個操作
  • 設(shè)置同步信號量 S, 初始為 0
  • 在“前操作”之后執(zhí)行 V(S)
  • 在“后操作”之前執(zhí)行 P(S)
  • 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)系都是一個進程同步問題(需要保證一前一后的操作)因此,

  • 要為每一對前驅(qū)關(guān)系各設(shè)置一個同步信號量
  • 在“前操作”之后對相應(yīng)的同步信號量執(zhí)行V 操作
  • 在“后操作”之前對相應(yīng)的同步信號量執(zhí)行P 操作
  • 經(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)系(從事件角度分析)
  • 桌上有組合 1 -> 第 1 個抽煙者取走東西
  • 桌上有組合 2 -> 第 2 個抽煙者取走東西
  • 桌上有組合 3 -> 第 3 個抽煙者取走東西
  • 發(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ā)生呢?

    有很多種方式,舉幾個例子:

  • 最多允許四個哲學(xué)家同時進餐,這樣保證至少有一個哲學(xué)家能拿到左右兩只筷子.
  • 奇數(shù)號哲學(xué)家先拿左邊的筷子再拿右邊的筷子,偶數(shù)號哲學(xué)家相反。這樣保證如果相鄰的兩個奇偶號哲學(xué)家都想吃飯,那么只會有其中一個可以拿起第一只筷子。
  • 僅當(dāng)一個哲學(xué)家左右兩支筷子都可用時,才允許他抓起筷子。
  • 代碼

    思想:使用 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ù)其他語言都沒有管程。

    管程的特征
  • 局部于管程的數(shù)據(jù)只能被局部于管程的過程所訪問
  • 一個進程只有通過調(diào)用管程內(nèi)的過程,才能進入管程訪問共享數(shù)據(jù)
  • 每次只允許一個進程在管程內(nèi)執(zhí)行某個內(nèi)部過程
  • 死鎖

    易混概念辨析

    死鎖:各進程互相等待對方手里的資源,導(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)先級更高的進程使用)
    缺點
  • 實現(xiàn)起來比較復(fù)雜。
  • 釋放已獲得的資源可能造成前一階段工作的失效,因此只適用于易保存和恢復(fù)狀態(tài)的資源,如CPU。
  • 反復(fù)申請釋放資源,增加系統(tǒng)開銷,降低系統(tǒng)吞吐量。
  • 方案一會導(dǎo)致進程饑餓。
  • (3)破壞請求和保持條件
    請求和保持條件

    進程已經(jīng)保持了至少一個資源,但又提出了新的資源請求,而該資源又被其他進程占有,此時請求進程被阻塞,但又對自己已有的資源保持不放。

    方案

    采用 靜態(tài)分配 方法,進程在運行前,一次申請完它需要的全部資源才能投入運行。一旦投入運行,一直保持資源,且不再請求別的任何資源,直到運行結(jié)束,釋放資源。

    缺點
  • 進程整個運行期間一直保持所有資源,造成資源浪費
  • 可能導(dǎo)致某些進程饑餓(請求資源多的進程難以集齊所有資源)
  • (4)破壞循環(huán)等待條件
    循環(huán)等待條件

    存在一種進程資源的循環(huán)等待鏈,鏈中的每一個進程已獲得的資源同時被下一個進程所請求。

    方案

    順序資源分配法。首先給系統(tǒng)中的資源編號,規(guī)定每個進程必須按編號遞增的順序請求資源,同類資源(即編號相同的資源)一次申請完。

    原理

    一個進程只有已占有小編號的資源時,才有資格申請更大編號的資源。

    • 任一時刻,總有一進程擁有的資源編號是最大的,此進程對其余資源的獲取必暢通無阻
    • 已持有大編號資源的進程不可能逆向地回來申請小編號的資源,從而就不會產(chǎn)生循環(huán)等待的現(xiàn)象
    缺點:
  • 不方便增加新的設(shè)備,因為可能需要重新分配所有的編號;
  • 進程實際使用資源的順序可能和編號遞增順序不一致,會導(dǎo)致資源浪費;
  • 必須按規(guī)定次序申請資源,用戶編程不便。
  • 2、避免死鎖

    用某種方法防止系統(tǒng)進入不安全狀態(tài),從而避免死鎖(銀行家算法)

    銀行家算法

    一個小城鎮(zhèn)的銀行家向一群客戶分別承諾了一定的貸款額度,只有當(dāng)借款總數(shù)達到客戶最大要求時,客戶才歸還貸款,否則無論之前借了多少錢,都拿不回來。

    銀行家算法的步驟:
  • 檢查此次申請是否超過之前聲明的最大需求數(shù)
  • 檢查此時系統(tǒng)剩余可用資源是否還能滿足此次請求
  • 試探分配,更各個改數(shù)據(jù)結(jié)構(gòu)
  • 用安全型算法檢查此次分配是否會導(dǎo)致系統(tǒng)進入不安全狀態(tài)
  • 安全性算法的步驟:
  • 檢查當(dāng)前剩余可用資源是否能滿足某個資源的最大需求,如果可以,就將該進程加入安全序列
  • 等到這個進程執(zhí)行完畢就將它占有的全部資源回收
  • 不斷重復(fù)上述過程,看看最終是否能讓所有進程都加入安全序列
  • 安全序列

    所謂的安全序列,就是指系統(tǒng)如果按照這種序列分配資源,則每個進程都能順利完成。只要能找出一個安全序列,系統(tǒng)就處于安全狀態(tài)。當(dāng)然,安全序列可以有多個。

    一個 找不到 安全序列的例子:(剩余資源總數(shù) 3 3 2)可以拓展到有 n 個進程,m 種資源

    進程最大需求已分配最多還需要
    P08 5 30 1 08 4 3
    P13 2 22 0 01 2 2
    P29 5 23 0 26 5 0
    P32 2 22 1 10 1 1
    P44 3 60 0 24 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)的進程。

    死鎖檢測算法:
  • 在資源分配圖中,找出既不阻塞又不是孤點的進程 Pi,消去它所有的請求邊和分配變,使之稱為孤立的結(jié)點。上圖中的 P1 是滿足這一條件的進程結(jié)點,于是將 P1 的所有邊消去。
  • 進程 Pi 所釋放的資源,可以喚醒某些等待這些資源的阻塞進程,原來的阻塞進程可能變?yōu)榉亲枞M程(下圖 P2)。重復(fù)整個過程,若能消去途中所有的邊,則稱該圖是可完全簡化的。
  • 解除死鎖方法:
  • 資源剝奪法。掛起(暫時放到外存上)某些死鎖進程,并搶占它的資源,分配給其他的死鎖進程。
  • 撤銷進程法(或稱終止進程法)。強制撤銷部分、甚至全部死鎖進程,并剝奪這些進程的資源。
  • 進程回退法。讓一個 / 多個死鎖進程回退到足以避免死鎖的地步。要求系統(tǒng)要記錄進程的歷史信息,設(shè)置還原點。
  • 總結(jié)

    以上是生活随笔為你收集整理的操作系统:第二章 进程管理3 - 进程同步与互斥的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。