管程類型是由程式員定義的一組在管程内互斥操作的類型
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL90TQkxWNtxUdSJzYqVTeaZHetlVdRhEZwQWbixGatVmb1cVY1kTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcukzN1QzMycTM1ITOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
管程會保證隻有一個程序在管程的執行。(使得所有的程序都互斥)
管程的隊列: 等待隊列(多個) + 就緒隊列 + 外部等待隊列
管程的實作
管程
Monitors were invented by Per Brinch Hansen[1] and C. A. R. Hoare,[2] and were first implemented in Brinch Hansen’s Concurrent Pascal language.[3]
在信号量機制中,每個要通路臨界資源的程序都必須自備同步的PV操作,大量分散的同步操作會給系統管理帶來麻煩,且容易因為同步操作不當而導緻系統死鎖。于是便産生了一種新的程序同步工具——管程(Monitors)。
管程中包含條件變量,用于管理程序的阻塞和喚醒。
其形式為 condition x;對它的操作僅有wait和signal。
- x.wait:正在調用管程的程序因 x 條件需要被阻塞或挂起,則調用 x.wait 将自己插入到 x 條件的等待隊列上,并釋放管程,直到 x 條件變化。此時其它程序可以使用該管程。
- x.signal:正在調用管程的程序發現 x 條件發生了變化,則調用 x.signal,重新啟動一個因 x 條件而阻塞或挂起的程序。(與信号量的signal不同,沒有s:=s+1的操作)
引入管程的原因
信号量機制的缺點:程序自備同步操作,P(S)和V(S)操作大量分散在各個程序中,不易管理,易發生死鎖。1974年和1977年,Hore和Hansen提出了管程。
管程特點
管程封裝了同步操作,對程序隐蔽了同步細節,簡化了同步功能的調用界面。使用者編寫并發程式如同編寫順序(串行)程式。
引入管程機制的目的
- 把分散在各程序中的臨界區集中起來進行管理;
- 防止程序有意或無意的違法同步操作;
- 便于用進階語言來書寫程式,也便于程式正确性驗證。
管程的定義
管程是由局部于自己的若幹公共變量及其說明和所有通路這些公共變量的過程所組成的軟體子產品。
組成部分
- 局部于管程的共享變量;
- 對資料結構進行操作的一組過程;
- 對局部于管程的資料進行初始化的語句。
管程的屬性
- 共享性:管程可被系統範圍内的程序互斥通路,屬于共享資源
- 安全性:管程的局部變量隻能由管程的過程通路,不允許程序或其它管程直接通路,管程也不能通路非局部于它的變量。
- 互斥性:多個程序對管程的通路是互斥的。任一時刻,管程中隻能有一個活躍程序。
- 封裝性:管程内的資料結構是私有的,隻能在管程内使用,管程内的過程也隻能使用管程内的資料結構。程序通過調用管程的過程使用臨界資源。管程在Java中已實作。
管程的組成結構
- 局部資料和條件變量組成管程内的資料結構;
- 過程/函數1~過程/函數k組成管程内的一組過程對管程内的資料結構進行操作;
- 初始化代碼對管程内的資料結構進行初始化。
管程入口處的等待隊列
管程是互斥進入的,是以當一個程序試圖進入一個巳被占用的管程時它應當在管程的入口處等待,因而在管程的入口處應當有一個程序等待隊列,稱作入口等待隊列。
管程内的資源等待隊列
管程是用于管理資源的,當進入管程的程序因資源被占用等原因不能繼續運作時使其等待,即将等待資源的程序加入資源等待隊列,該隊列由條件變量維護。資源等待隊列可以由多個,每種資源一個隊列。
條件變量
條件變量(例如名稱為c)是管程内的一種資料結構,且隻有在管程中才能被通路,它對管程内的所有過程是全局的,隻能通過兩個原語操作來控制它。
c.wait( )-調用程序阻塞并移入與條件變量c相關的隊列中,并釋放管程,直到另一個程序在該條件變量c上執行signal( )喚醒等待程序并将其移出條件變量c隊列。
c.signal( )-如果存在其他程序由于對條件變量c執行wait( )而被阻塞,便釋放之;如果沒有程序在等待,那麼,信号被丢棄。
條件變量與P、V操作中信号量的差別:
條件變量是一種信号量,但不是P、V操作中純粹的計數信号量,沒有與條件變量關聯的值,不能像信号量那樣積累供以後使用,僅僅起到維護等待程序隊列的作用。是以在使用條件變量x時,通常需要定義一個與之配套使用的整型變量x-count用于記錄條件變量x所維護等待隊列中的程序數。
管程内的緊急等待隊列
當一個進入管程的程序執行等待操作wait時,其它程序應該被允許進入管程;
當一個進入管程的程序執行喚醒操作signal時(如P喚醒Q),管程中便存在兩個同時處于活動狀态的程序,由于任一時刻,管程中隻能有一個活躍程序。是以處理辦法為:
1)P等待Q繼續,直到Q退出或等待
2)Q等待P繼續,直到P等待或退出
3)規定喚醒signal為管程中最後一個可執行的操作
https://baike.baidu.com/item/%E7%AE%A1%E7%A8%8B/10503922?fr=aladdin