日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

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

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

本文已收錄至 Github(MD-Notes),若博客中有圖片打不開,可以來我的 Github 倉庫:https://github.com/HanquanHq/MD-Notes,涵蓋了互聯網大廠面試必問的知識點,講解透徹,長期更新中,歡迎一起學習探討。
面試必會系列專欄:https://blog.csdn.net/sinat_42483341/category_10300357.html
操作系統系列專欄:https://blog.csdn.net/sinat_42483341/category_10519484.html


第二章 進程管理3 - 進程同步與互斥

目錄

  • 第二章 進程管理3 - 進程同步與互斥
      • 什么是進程同步
      • 進程互斥的原則
      • 進程互斥的軟件實現方法
        • 1、單標志法
        • 2、雙標志先檢查法
        • 3、雙標志后檢查法
        • 4、Peterson 算法
      • 進程互斥的硬件實現方法
        • 1、中斷屏蔽方法
        • 2、TestAndSetLock 指令
          • TSL和中斷屏蔽的區別
          • 利用TSL完成進程間互斥 - 《現代操作系統》P71
        • 3、XCHG 指令
      • 信號量機制
        • 1、整型信號量
        • 2、記錄型信號量(默認)
          • 記錄型信號量定義
          • P 操作(wait 操作)
          • V 操作(signal 操作)
        • 信號量機制實現進程互斥
        • 信號量機制實現進程同步 - 前 V 后 P
        • 信號量機制實現前驅關系 - 前 V 后 P
    • 經典的 IPC 問題
      • 多生產者 - 多消費者問題
          • 分析同步關系(一前一后):
          • 代碼
      • 吸煙者問題
        • 可以生產多個產品的單生產者問題
        • 分析關系
          • 三種組合
          • 同步關系(從事件角度分析)
          • 代碼
      • 讀者寫者問題
          • 代碼
      • 哲學家就餐問題
          • 關系分析
          • 如何防止死鎖的發生呢?
          • 代碼
    • 管程
          • 管程的特征
    • 死鎖
        • 易混概念辨析
        • 死鎖產生的必要條件
          • 1、互斥條件
          • 2、不剝奪條件
          • 3、請求和保持條件
          • 4、循環等待條件
        • 什么時候會發生死鎖
          • 1、對系統資源的競爭
          • 2、進程推進順序非法
          • 2、信號量的使用不當
      • 死鎖的處理策略
        • 1、預防死鎖
          • (1)破壞互斥條件
            • 方案
            • 缺點:
          • (2)破壞不剝奪條件
            • 不剝奪條件
            • 方案
            • 缺點
          • (3)破壞請求和保持條件
            • 請求和保持條件
            • 方案
            • 缺點
          • (4)破壞循環等待條件
            • 循環等待條件
            • 方案
            • 原理
            • 缺點:
        • 2、避免死鎖
          • 銀行家算法
            • 銀行家算法的步驟:
            • 安全性算法的步驟:
          • 安全序列
        • 3、死鎖的檢測和解除
          • 死鎖檢測思想:
          • 死鎖檢測算法:
          • 解除死鎖方法:


什么是進程同步

知識點回顧:進程具有異步性的特征。異步性是指,各并發執行的進程以各自獨立的、不可預知的速度向前推進。

由于并發必然導致異步性。而實際應用中,又必須按照某種順序執行,如何解決這種異步問題,就是“進程同步”所討論的內容。

同步 亦稱直接 制約關系,它是指為完成某種任務而建立的兩個或多個進程,這些進程因為需要在某些位置上 協調它們的工作次序 而產生的制約關系。

對臨界資源的互斥訪問,可以在邏輯上分為如下四個部分:

進程互斥的原則

為了實現對臨界資源的互斥訪問,同時保證系統整體性能,需要遵循以下原則:

  • 空閑讓進。臨界區空閑時,可以允許一個請求進入臨界區的進程立即進入臨界區;
  • 忙則等待。當已有進程進入臨界區時,其他試圖進入臨界區的進程必須等待;
  • 有限等待。對請求訪問的進程,應保證能在有限時間內進入臨界區(保證不會饑餓);
  • 讓權等待。當進程不能進入臨界區時,應立即釋放處理機,防止進程忙等待。
  • 進程互斥的軟件實現方法

    1、單標志法

    算法思想:兩個進程在訪問完臨界區后會把使用臨界區的權限轉交給另一個進程。也就是說,每個進程進入臨界區的權限只能被另一個進程賦予。

    turn 的初值為 0,即剛開始只允許 0 號進程進入臨界區。

    該算法可以實現同一時刻最多只允許一個進程訪問臨界區,但是兩個進程必須輪流訪問。如果 P0 一直不訪問臨界區,雖然臨界區空閑,但并不允許 P1 訪問。違背“空閑讓進”原則

    2、雙標志先檢查法

    算法思想:設置一個布爾型數組flag[],數組中各個元素用來標記各進程想進入臨界區的意愿,比如“flag[0] = ture”意味著0 號進程P0 現在想要進入臨界區。每個進程在進入臨界區之前先檢查當前有沒有別的進程想進入臨界區,如果沒有,則把自身對應的標志flag[i] 設為true,之后開始訪問臨界區。

    由于進入區的“檢查”和“上鎖” 兩個處理不是一氣呵成的,“檢查”后、“上鎖”前 可能發生進程切換。

    主要問題是:**違反“忙則等待”**原則,并發時可能導致兩個進程同時訪問臨界區。

    3、雙標志后檢查法

    先“上鎖”后“檢查”的方法,來避免上述問題。

    若按照①⑤②⑥的順序執行,P0 和 P1 將無法進入臨界區。

    此方法雖然 解決了“忙則等待” 的問題,但是又 違背了“空閑讓進”、“有限等待”原則

    4、Peterson 算法

    算法思想:結合雙標志法、單標志法的思想。如果雙方都爭著想進入臨界區,那可以讓進程嘗試謙讓

    誰最后設置了 turn 的值,誰就失去了行動的優先權。

    Peterson 算法用軟件方法解決了進程互斥問題,遵循了空閑讓進、忙則等待、有限等待三個原則,但是依然未遵循讓權等待的原則(進程無法獲得使用權的時候,一直while循環檢測,消耗CPU資源)。

    Peterson 算法相較于之前三種軟件解決方案來說是最好的,但依然不夠好。

    進程互斥的硬件實現方法

    1、中斷屏蔽方法

    與原語的實現思想相同,即在某進程開始訪問臨界區到結束訪問為止,都不允許被中斷。

    開中斷; 臨界區; 關中斷;

    優點:

    • 簡單,高效

    缺點:

    • 不適用于多處理機
    • 由于開/關中斷指令是特權指令,只能運行在內核態,因此只適用于內核級進程,不適用于用戶級進程

    2、TestAndSetLock 指令

    TSL 是 Test and Set Lock 的縮寫。要實現 TSL 需要硬件的支持。

    硬件指令:

    TSL RX, LOCK # 測試并加鎖

    該指令所做的事情:

    • 讀取 Lock 的值,存入寄存器RX中
    • 給 Lock 設置一個非0值(設置到LOCK對應的內存中)

    以上三個步驟是一個 不可拆分 的原子操作,執行該指令的CPU將會 鎖住內存總線(memory bus),以禁止其他CPU在本指令結束之前訪問內存。

    TSL和中斷屏蔽的區別

    當一個CPU將中斷屏蔽后,只影響當前屏蔽中斷的CPU,其他CPU還是依然可以照樣訪問內存的(想要中斷)。唯一一個當一個CPU在訪問內存時阻止其他CPU訪問內存的方法就是將內存總線鎖住,這個需要硬件的支持,TSL可以達到該目的。

    利用TSL完成進程間互斥 - 《現代操作系統》P71
    enter_region:TSL REGISTER, LOCK /*復制鎖到寄存器并將鎖置1*/CMP REGISTER, #0 /*判斷寄存器內容是否為0*/JNE enter_region /*若不是0,說明鎖已經被設置,跳轉到enter_region循環*/RET /*返回調用者,進入臨界區*/leave_region:MOVE LOCK, #0 /*在鎖中置0*/RET /*返回調用者*/
  • 如果LOCK的值為0,則將LOCK的值設置為1,且進入臨界區
  • 如果LOCK的值為1,則一直循環等待
  • 如果多個進程同時調用TSL,利用TSL的特性:只有一個進程訪問,其他的會被block
  • (下圖圖源王道)

    3、XCHG 指令

    一個可替換 TSL 的指令是 XCHG,它原子性地交換了兩個位置的內容。它本質上與 TSL 的解決方法一樣。

    enter_region:MOVE REGISTER, #1 /*給寄存器中置1*/XCHG REGISTER, LOCK /*交換寄存器與鎖變量的內容*/CMP REGISTER, #0 /*判斷寄存器內容是否為0?*/JNE enter_region /*若不是0跳轉到enter_region*/RET /*返回調用者,進入臨界區*/ leave_region:MOVE LOCK, #0 /*在鎖中置0*/RET /*返回調用者*/

    優點:

    • 使用硬件方式實現簡單;適用于多處理機環境

    缺點:

    • 不滿足“讓權等待”原則,暫時無法進入臨界區的進程會占用 CPU 資源并循環執行 TSL 指令,導致忙等

    信號量機制

    以上所有方案都無法實現讓權等待,而信號量機制實現了讓權等待。

    用戶進程通過使用操作系統提供的一對原語來對信號量進行操作,實現了進程互斥、進程同步。

    • P 操作:申請 / wait(S) / P(S)

    • V 操作:釋放 / signal(S) / V(S)

    1、整型信號量

    用一個 整數型的變量 作為信號量,表示系統中某種資源的數量。對信號量的三種操作:

    • 初始化
    • P 操作(將“檢查”和“上鎖”一氣呵成,避免并發 / 異步導致的問題)
    • V 操作

    存在的問題:不滿足“讓權等待”原則,會發生“忙等”,一直 while 占用處理機

    2、記錄型信號量(默認)

    記錄型信號量定義

    S.value 表示系統中某種資源的數目。

    P 操作(wait 操作)

    對信號量 S 執行一次 P 操作,即執行 S.value–,表示資源數減 1

    若 S.value < 0 時,該資源已分配完畢,進程調用 block 原語自我阻塞(運行態 -> 阻塞態),主動放棄處理機,并插入該類資源的等待隊列 S.L 中。遵循了“讓權等待”原則。

    V 操作(signal 操作)

    對信號量 S 執行一次 V 操作,即執行 S.value++,表示資源數加 1

    若 S.value <= 0,仍有進程在等待資源,則調用 wakeup 原語喚醒等待隊列中第一個進程(阻塞態 -> 就緒態)

    信號量機制實現進程互斥

  • 分析并發進程的關鍵活動,劃定臨界區(如:對臨界資源打印機的訪問就應放在臨界區)
  • 設置互斥信號量 mutex,初值為 1
  • 在進入區 P(mutex)——申請資源
  • 在退出區 V(mutex)——釋放資源
  • 信號量機制實現進程同步 - 前 V 后 P

  • 分析什么地方需要實現“同步關系”,即必須保證“一前一后”執行的兩個操作
  • 設置同步信號量 S, 初始為 0
  • 在“前操作”之后執行 V(S)
  • 在“后操作”之前執行 P(S)
  • P2 需要這種資源,而只有 P1 才能產生這種資源。即,只有執行了 V 操作之后,P 操作之后的代碼才會執行。

    信號量機制實現前驅關系 - 前 V 后 P

    進程P1 中有句代碼S1,P2 中有句代碼S2 ,P3中有句代碼S3 …… P6 中有句代碼S6。這些代碼要求按如下前驅圖所示的順序來執行:

    其實每一對前驅關系都是一個進程同步問題(需要保證一前一后的操作)因此,

  • 要為每一對前驅關系各設置一個同步信號量
  • 在“前操作”之后對相應的同步信號量執行V 操作
  • 在“后操作”之前對相應的同步信號量執行P 操作
  • 經典的 IPC 問題

    生產者、消費者共享一個初始為空、大小為n的緩沖區。緩沖區是臨界資源,各進程必須互斥地訪問。

    • 若緩沖區 不滿,生產者可以 生產 -> V(full) 釋放

    • 若緩沖區 非空,消費者可以 消費 -> P(full) 申請

    仍然滿足 前 V 后 P:consumer 需要這種資源,而只有 producer 才能產生這種資源。即,只有執行了 V(full) 操作之后,P(full) 操作之后的代碼才會執行。

    semaphore mutex = 1; // 互斥信號量,實現對緩沖區的互斥訪問 semaphore empty = n; // 同步信號量,表示空閑緩沖區的數量 semaphore full = 0; // 同步信號量,表示產品的數量,也即非空緩沖區的數量producer (){ // 生產者while(1){生產一個產品;P(empty); // 實現互斥的 P 操作必須在實現同步的 P 操作之后,否則會導致死鎖P(mutex);把產品放入緩沖區;V(mutex); // 可以改變相鄰 V 操作的順序V(full);} }consumer (){ // 消費者while(1){P(full);P(mutex);從緩沖區取出一個產品;V(mutex);V(empty);使用產品;} }

    多生產者 - 多消費者問題

    桌上有一盤子,每次只能放入一個水果。爸爸只放蘋果,媽媽只放橘子,兒子只吃橘子,女兒只吃蘋果。

    盤子空才能放,盤子有正確的水果才能取。用 PV 操作實現上述過程。

    生產者生產的產品、消費者消費的產品類別各不相同。

    分析同步關系(一前一后):
  • 父親將蘋果放入盤子后,女兒才能取蘋果
  • 母親將橘子放入盤子后,兒子才能取橘子
  • 只有盤子為空時,父親或母親才能放入水果
  • 總結:在生產者-消費者問題中,如果緩沖區大小為1,那么有可能不需要設置互斥信號量就可以實現互斥訪問緩沖區的功能。這不是絕對的,要具體問題具體分析。

    建議:在考試中如果來不及仔細分析,可以加上互斥信號量,保證各進程一定會互斥地訪問緩沖區。但需要注意的是,實現互斥的 P 操作一定要在實現同步的 P 操作之后,否則可能引起“死鎖”。

    代碼
    // semaphore mutex = 1; // 實現互斥訪問盤子(緩沖區) semaphore apple = 0; // 盤子中有幾個蘋果 semaphore orange = 0; // 盤子中有幾個橘子 semaphore plate = 1; // 盤子中還可以放多少個水果 dad (){while(1){準備一個蘋果;P(plate); // P 申請盤子里的一個空位把蘋果放入盤子;V(apple); // V 釋放一個蘋果} } mom (){while(1){準備一個橘子;P(plate);把橘子放入盤子;V(orange);} } daughter (){while(1){P(apple); // P 申請一個蘋果從盤中取出蘋果;V(plate); // V 釋放盤子一個空位吃掉蘋果;} } son(){while(1){P(orange);從盤中取出橘子;V(plate);吃掉橘子;} }

    吸煙者問題

    可以生產多個產品的單生產者問題

    系統中有 三個抽煙者進程,每個抽煙者不斷地卷煙并抽煙。抽煙者卷起并抽掉一顆煙需要有三種材料:煙草、紙、膠水。一個抽煙者有煙草,一個有紙,另一個有膠水。

    系統中還有 一個供應者進程,它們無限地供應所有三種材料,但每次僅輪流提供三種材料中的兩種。

    得到缺失的兩種材料的抽煙者在卷起并抽掉一顆煙后,會發信號通知供應者,讓它繼續提供另外的兩種材料。這一過程重復進行。

    請用以上介紹的 IPC 同步機制編程,實現該問題要求的功能。

    分析關系

    桌子:容量為1的緩沖區,要互斥訪問

    三種組合
  • 紙 + 膠水
  • 煙草 + 膠水
  • 煙草 + 紙
  • 同步關系(從事件角度分析)
  • 桌上有組合 1 -> 第 1 個抽煙者取走東西
  • 桌上有組合 2 -> 第 2 個抽煙者取走東西
  • 桌上有組合 3 -> 第 3 個抽煙者取走東西
  • 發出完成信號 -> 供應者將下一個組合放到桌上

    代碼

    不需要設置一個專門的同步信號量。因為緩沖區大小為 1,故同一時刻,四個同步信號量中至多有一個為 1。

    semaphore offer1 = 0; // 桌上組合一的數量 semaphore offer2 = 0; // 桌上組合二的數量 semaphore offer3 = 0; // 桌上組合三的數量 semaphore finish = 0; // 抽煙是否完成 int i = 0; // 用于實現“三個抽煙者輪流流抽煙”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);} }

    讀者寫者問題

    有讀者、寫者兩組并發進程,共享一個文件。規則:

    • 允許 多個讀者 同時 文件
    • 只允許 一個寫者 寫文件
    • 寫完成 之前 不允許讀
    • 讀完成 之前 不允許寫

    互斥關系

    • 互斥:寫 - 寫 / 寫 - 讀

    • 不互斥:讀 - 讀

    代碼

    讀寫公平法:即使連續有 多個讀者 到來,也 不會使寫者一直饑餓,是相對公平的先來連服務原則。

    semaphore rw = 1; // 讀寫信號量,實現只讀或只寫(互斥訪問) int count = 0; // 記錄當前有幾個讀者程在訪問文件 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);} }

    哲學家就餐問題

    圓桌坐著 5 名哲學家,每兩個哲學家之間有一根筷子,哲學家交替進行思考和進餐。進餐時,試圖一根一根拿起左、右兩根筷子,只有同時拿起兩根筷子才能進餐,否則需要等待。進餐完畢后,哲學家放下筷子繼續思考。

    關系分析
    • 5 個哲學家進程
    • 相鄰哲學家對中間筷子的訪問是互斥關系

    每個哲學家進程需要同時持有兩個臨界資源才能開始吃飯。如何避免死鎖現象,才是哲學家問題的精髓。

    定義互斥信號量數組 chopstick[5] = {1, 1, 1, 1, 1} 用于實現對 5 個筷子的互斥訪問。并對哲學家按 0 ~ 4 編號,哲學家 i 左邊的筷子編號為 i,右邊的筷子編號為 (i + 1) % 5

    如何防止死鎖的發生呢?

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

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

    思想:使用 mutex 來實現 只允許一個哲學家 處于 只拿起了一只筷子的狀態

    semaphore chopstick[5]={1,1,1,1,1}; semaphore mutex = 1; // 互斥地取筷子 Pi (){ // i 號哲學家的進程while(1){P(mutex);P(chopstick[i]); // 拿左P(chopstick[(i+1)%5]); // 拿右V(mutex);吃飯;V(chopstick[i]); // 放左V(chopstick[(i+1)%5]); // 放右思考;} }

    管程

    《現代操作系統》P79

    由于使用信號量時要非常小心,而且出現的錯誤都是競爭條件、死鎖以及其它一些不可預測或不可再現的行為,而為了更易于編寫正確的程序,提出了一種高級同步原語,稱為管程(monitor)

    一個 管程 是由一個過程、變量及數據結構等組成的一個集合,它們組成一個 特殊的模塊軟件包

    管程有一個很重要的特性:任一時刻,管程中只能有一個活躍進程。

    管程是編程語言的組成部分,編譯器知道它們的特殊性,因此可以采用與其它過程調用不同的方法來處理對管程的調用。由編譯器而非程序員來安排互斥,出錯的可能性要小很多。

    • Java 的 syncronized 就是一個管程,也可使用 wait() / notify() 實現進程的同步。

    • C,Pascal 以及多數其他語言都沒有管程。

    管程的特征
  • 局部于管程的數據只能被局部于管程的過程所訪問
  • 一個進程只有通過調用管程內的過程,才能進入管程訪問共享數據
  • 每次只允許一個進程在管程內執行某個內部過程
  • 死鎖

    易混概念辨析

    死鎖:各進程互相等待對方手里的資源,導致各進程都阻塞,無法向前推進(操作系統考慮)

    饑餓:由于長期得不到想要的資源,某進程無法向前推進(操作系統考慮)

    死循環:某進程執行過程中一直跳不出某個循環,是可以上處理機運行的(開發人員考慮)

    死鎖產生的必要條件

    1、互斥條件

    只有對必須互斥使用的資源的爭搶才會導致死鎖(如哲學家的筷子、打印機設備)。像內存、揚聲器這樣可以同時讓多個進程使用的資源是不會導致死鎖的(因為進程不用阻塞等待這種資源)。

    2、不剝奪條件

    進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放。

    3、請求和保持條件

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

    4、循環等待條件

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

    什么時候會發生死鎖

    1、對系統資源的競爭

    各進程對不可剝奪的資源(如打印機)的競爭可能引起死鎖,對可剝奪的資源(CPU)的競爭是不會引起死鎖的。

    2、進程推進順序非法

    請求和釋放資源的順序不當,也同樣會導致死鎖。例如,并發執行的進程P1、P2 分別申請并占有R1、R2,之后進程P1申請R2,進程P2申請R1,兩者因為申請的資源被對方占有而阻塞,發生死鎖。

    2、信號量的使用不當

    如生產者-消費者問題中,如果實現互斥的P操作在實現同步的P操作之前,就有可能導致死鎖。(可以把互斥信號量、同步信號量也看做是一種抽象的系統資源)

    死鎖的處理策略

    1、預防死鎖

    破壞死鎖產生的四個必要條件中的一個或幾個。

    (1)破壞互斥條件
    方案

    把只能互斥使用的資源改造為允許共享使用,則系統不會進入死鎖狀態。比如,操作系統可以采用 SPOOLing 技術把獨占設備在邏輯上改造成共享設備。

    缺點:

    并不是所有的資源都可以改造成可共享使用的資源。很多時候無法破壞互斥條件。

    (2)破壞不剝奪條件
    不剝奪條件

    進程所獲得的資源在未使用完之前,不能由其他進程強行奪走,只能主動釋放。

    方案
    • 方案一:當某個進程請求新的資源得不到滿足時,它必須立即釋放保持的所有資源,待以后需要時再重新申請。也就是說,即使某些資源尚未使用完,也需要主動釋放,從而破壞了不可剝奪條件。
    • 方案二:當某個進程需要的資源被其他進程所占有的時候,可以由操作系統協助,將想要的資源強行剝奪。這種方式一般需要考慮各進程的優先級(比如:剝奪調度方式,就是將處理機資源強行剝奪給優先級更高的進程使用)
    缺點
  • 實現起來比較復雜。
  • 釋放已獲得的資源可能造成前一階段工作的失效,因此只適用于易保存和恢復狀態的資源,如CPU。
  • 反復申請釋放資源,增加系統開銷,降低系統吞吐量。
  • 方案一會導致進程饑餓。
  • (3)破壞請求和保持條件
    請求和保持條件

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

    方案

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

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

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

    方案

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

    原理

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

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

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

    銀行家算法

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

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

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

    一個 找不到 安全序列的例子:(剩余資源總數 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、死鎖的檢測和解除

    允許死鎖的發生,不過操作系統會負責檢測出死鎖的發生,然后采取某種措施解除死鎖。

    • 死鎖檢測算法:用于檢測系統狀態,以確定系統中是否發生了死鎖。
    • 死鎖解除算法:當認定系統中已經發生了死鎖,利用該算法可將系統從死鎖狀態中解脫出來。

    死鎖檢測思想:

    依次消除與不阻塞進程相連的邊,直到無邊可消。

    • 如果最終 能消除所有邊,就稱這個圖是可完全簡化的。此時一定沒有發生死鎖(即找到一個 安全序列

    • 如果最終 不能消除所有邊,那么此時就是 發生了死鎖。剩余連著邊的進程,就是處于死鎖狀態的進程。

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

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。