Operating System-進程/線程內部通信-管程(Monitor)介紹,實現以及應用

来源:http://www.cnblogs.com/Brake/archive/2016/01/02/Operating_System_Monitor.html
-Advertisement-
Play Games

本文主要內容:1)管程(Monitor)介紹;2)管程實現;3)管程應用


本文主要內容:

  • 管程(Monitor)介紹
  • 管程實現
  • 管程應用

一、管程(Monitor)介紹

1.1 管程

前一篇文章介紹了信號量以及使用,信號量已經提供了一個方便且高效的進程同步機制,但是信號量有個缺點就是每次都需要程式員專門的去調用PV操作,如果程式員由於大意調用錯了PV操作,比如該調用P操作的時候卻調用了V操作,該針對X信號量調用P操作,卻對Y信號量調用了P操作。這種錯誤是非常危險的,因為進程同步的問題不是每次都能重現,比如前面的錯誤在測試環境可能不會出現錯誤,但是到了生產環境就有可能出現,且無法重現。

為瞭解決上述問題,引入了管程(Monitor),信號量是操作系統層面的結構,管程是一個程式結構,由編程語言封裝,最終由編譯器:

  • 一個管程定義了一個數據結構和能夠併發進程所執行的一組操作,這組操作能同步進程和改變管程中的數據
  • 進程可以調用管程的操作,但是不能訪問管程的內部數據結構
  • 它表示一個對象自己維護自己的狀態,並且能夠根據自身狀態來同步併發的線程操作,而不是把這種同步的手段交給調用者來處理。
  • 管程保證同一時間只有一個進程處在管程內部的方法內
monitor MonitorName
{
    //shared variable declarations
    procedure P1(...)
    {

    }
    procedure P2(...)
    {
    
    }

    procedure P3(...)
    {
    
    }

    procedure PN(...)
    {
    
    }

    initialization code(...)
    {

    }
}

1.2 條件(Condition variables)

只有管程是不夠的,在生產者消費者的例子中,當發現buffer中如果已經沒有item的時候,消費者如何block自己呢?介於這個原因,又引入了條件變數(Condition Variables)。條件變數同時提供了兩個方法:P以及V用於block和unblock。

二、管程實現

管程通過隊列來跟蹤那些嘗試著想訪問管程的進程,為了排他訪問,管程必須得有一個鎖,訪問管程的進程會得到這個鎖,其他嘗試訪問管程的進程就得block。被block的進程會被放入隊列,等待被unblock。

管程的實現中有如下的隊列:

  1. 進入隊列(Entry Queue),保存嘗試從外部訪問管程程式的進程,每個管程至少有一個進入隊列
  2. 被喚醒的隊列(Signaller Queue),保存剛剛執行了V操場的進程(signal)
  3. 等待隊列(Waiting Queue),保存剛剛被V操作喚醒的進程
  4. 條件變數隊列(Condition Variable Queue),保存剛剛執行了條件變數Wait(P)操作的進程

三、管程應用

 上一篇文章針對哲學家用餐給出的解決方案有個問題:當所有哲學家同時拿起筷子想吃飯的時候就會發生死鎖,所有哲學家都會一直處於等待狀態。本文用管程給出瞭解決方案,哲學家吃飯得滿足的條件:

  1. 哲學家餓(hungry)
  2. 哲學家的左右鄰居都沒有吃飯

如果滿足上麵條件,則哲學家便可以拿起筷子進行用餐,否則哲學家就得等待

monitor dp
{
   enum {thinking, hungry, eating} state[5];
   condition self[5];

   void pickup(int i) {
      state[i] = hungry;
      test(i);
      if (state[i] != eating)
         self[i].wait();//P操作
   }

   void putdown(int i) {
      state[i] = thinking;
      test( (i+4)%5 );
      test( (i+1)%5 );
   }

   void test(int i) {
      if ((state[(i+4)%5] != eating) &&
          (state[i] == hungry) &&
          (state[(i+1)%5] != eating)) {
         state[i] = eating;
         self[i].signal();//V操作
      }
   }

   void init() {
      for (int i = 0; i < 5; i++)
         state[i] = thinking;
   }
}

Condition Self代表五個哲學家,當不能吃時候進行wait。

db.pickup(i);//找筷子
...
eating//吃
...
dp.putdown(i);//放下筷子

管程更多的是對資源的併發訪問做了一次封裝,感覺有很多OO編程的思想,直接用信號量的話,各種控制會很發散,當然容易出錯,信號量本事是沒有問題的。但是使用容易出錯。且由於散髮在多出,出問題不好排查,也不好修複。

管程是一種編程思想,這種思想就是封裝,並且有DRY的感覺。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 標簽:fdisk分區概述我們管理的伺服器可能會隨著業務量的不斷增長造成磁碟空間不足的情況,在這個時候我們就需要增加磁碟空間,本章主要介紹如何使用fdisk分區工具創建磁碟分區和掛載分區,介紹兩種情況一種是對原有的磁碟的剩餘空間增加分區,第二種是對新添加的磁碟進行分區操作。擴展空間查看當前分區信息fd...
  • deepin linux 簡單配置
  • Yunduan CUIgraphical user interfaces make easy tasks easy, while command line interfaces make difficult tasks possiblePart 1 學習Shell1. 什麼是 Shell?Shell...
  • 一臺N3150機器作為編譯伺服器,跑xubuntu。同時可以作為代碼管理伺服器,也可以作為一個htpc使用,播放高清影片等。由於N3150的功耗只有6W,無風扇,因此可以保證一個比較安靜的環境。閱讀數據手冊,分析代碼,串口終端等都跑在XP下,可以映射網路磁碟訪問編譯伺服器上的文件。同時XP上安裝了硬...
  • 一、簡介 pkg-config用來檢索系統中安裝庫文件的信息。典型的是用作庫的編譯和連接。 二、實例 http://blog.chinaunix.net/uid-20595934-id-1918368.html 三、常見問題 1)PKG_CONFIG_PATH和PKG_CONFIG的路徑設置問題 h...
  • seq
    Linux 中seq 命令的用法用於產生從某個數到另外一個數之間的所有整數用法:seq [選項]... 尾數 或:seq [選項]... 首數 尾數 或:seq [選項]... 首數 增量 尾數‐f 選項 指定格式% 後面指定數字的位數 預設是"%g","%3g"那麼數字位數不足部分是空格seq ‐...
  • 2015年各大技術公司八仙過海,各顯神通。微軟在其中尤為顯目。以下是2015年微軟公司推出的十大技術視頻。按照瀏覽量排序,排在第一位的視頻有55萬次之多。Windows 10, HoloLens, Visual Studio 2015成了2015年微軟的重頭戲。No.1: Visual Studio...
  • 任務調度的使用1:設置任務。 crontab -e2:分配任務-每隔第一時間去執行 date > /home/mydata1 希望,每天凌晨兩點執行date >> /home/mydata2 可以在crontab -e中加入0 2 * * * date >> /home/mydata2調度文件的規則...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...