管程 (英語:Moniters,也稱爲監視器) 是一種程序結構,結構內的多個子程序(對象或模塊)造成的多個工做線程互斥訪問共享資源。這些共享資源通常是硬件設備或一羣變量。管程實現了在一個時間點,最多隻有一個線程在執行管程的某個子程序。與那些經過修改數據結構實現互斥訪問的併發程序設計相比,管程實現很大程度上簡化了程序設計。php
管程提供了一種機制,線程能夠臨時放棄互斥訪問,等待某些條件獲得知足後,從新得到執行權恢復它的互斥訪問。編程
管程是東尼·霍爾 [1] 與泊·派克·漢森 [2]提出的,並由泊·派克·漢森首次在並行Pascal中實現。東尼·霍爾證實了這與信號量是等價的。管程在當時也被用於單操做系統環境中的進程間通訊。數據結構
在編程語言Concurrent Pascal,Pascal-Plus,Modula-2,Modula-3,Mesa以及Java中都提供這個功能。併發
一個管程包含:編程語言
一個管程的程序在運行一個線程前會先取得互斥鎖,直到完成線程或是線程等待某個條件被知足纔會放棄互斥鎖。若每一個執行中的線程在放棄互斥鎖以前都能保證不變量成立,則全部線程皆不會致使競態條件成立。函數
如下這個銀行帳戶的提款/存款事務的管程是個簡單的例子:ui
monitor class Account { private int balance := 0 invariant balance >= 0 public method boolean withdraw(int amount) precondition amount >= 0 { if balance < amount then return false else { balance := balance - amount ; return true } } public method deposit(int amount) precondition amount >= 0 { balance := balance + amount } }
當一個線程執行管程中的一個子程序時,稱爲佔用(occupy)該管程. 管程的實現確保了在一個時間點,最多隻有一個線程佔用了該管程。這是管程的互斥鎖訪問性質。spa
當線程要調用一個定義在管程中的子程序時,必須等到已經沒有其它線程在執行管程中的某個子程序。操作系統
在管程的簡單實現中,編譯器爲每一個管程對象自動加入一把私有的互斥鎖。該互斥鎖初始狀態爲解鎖,在管程的每一個公共子程序的入口給該互斥鎖加鎖,在管程的每一個公共子程序的出口給該互斥鎖解鎖。線程
這個例子中的不變量是「任何操做運行前 balance 變量必須反映正確的餘額」。通常而言,不變量的條件不被寫在程序中,而在註解中有相關說明,然而Eiffel程序設計語言檢查不變量。