2.3.11 管程
知識來源: B站王道考研
為什麼要引入管程
信号量機制存在問題:編寫程式困難、易出錯。
管程的定義和基本特征
管程是一種特殊的軟體子產品,有:
- 局部于管程的共享資料結構說明;
- 對該資料結構進行操作的一組過程(函數);
- 對局部于管程的共享資料設定初始值的語句;
基本特征:
4. 局部于管程的資料隻能被局部于管程的過程所通路;
5. 一個進餐隻有通過調用管程内的過程才能進入管程通路共享資料;
6. 每次僅允許一個進餐在管程内執行某個内部過程。
static class Monitor{
private Item [] buffer = new Item[N];
private int count = 0;
public synchronized void insert(Item item){
if(count == N) this.wait();
buffer[count ++] = item;
if(count == 1) this.notify();
}
public synchronized remove(){
if(count == 0) this.wait();
count --;
if(count == N - 1) this.notify();
return buffer[count];
}
}
ProducerConsumer pc = new ProducerConsumer();
//生産者程序
producer(){
while(1){
item = 生産一個産品;
pc.insert(item);
}
}
//消費者程序
consumer(){
while(1){
item = pc.remove();
消費産品item;
}
}
引入管程的目的無非就是要更友善地實作己醜年互斥和同步。
- 需要在管程中定義共享資料(如生産者消費者問題的緩沖區)
- 需要在管程中定義用于通路這些共享塑膠的“入口” — — 其實就是一些函數。
- 隻有通過這些特定的“入口”才能通路共享資料
- 管程中有很多“入口”,但是每次隻能開放其中一個“入口”,并且隻能讓一個程序或線程進入(如:生産者消費者問題中,各程序需要互斥地通路共享緩沖區。管程的這種特性即可保證一個時間段内最多隻會有一個程序在通路緩沖區。注意:這種互斥特性是由編譯器負責實作的)
- 可在管程中設定條件變量及等待/喚醒操作以解決同步問題。可以讓一個程序或線程在條件變量上等待(此時,該程序應先釋放管程的使用權,也就是讓出“入口”);可以通過喚醒操作将等待在條件變量上的程序或線程喚醒。