程序同步的三個經典問題
阿新 • • 發佈:2018-12-31
1. 有限快取問題 Bounded-Buffer Problem
要求:
- producer和consumer,二者不能對buffer進行操作
- 當buffer滿的時候,就不允許producer繼續寫
- 當buffer空的時候,就不允許consumer繼續讀
訊號量及其初始化
Semaphore mutex = 1; //buffer的鎖
Semapore full = 0; //滿位的數量
Semaphore empty = n; //空位的數量
producer簡單程式碼描述
/*PV形式*/ while(true){ P(empty); P(mutex); //write... V(mutex); V(full); } /*wait signal形式*/ while(true){ wait(empty); wait(mutex); //write... signal(mutex); signal(full); }
consumer簡單程式碼描述
/*PV形式*/
while(true){
P(full);
P(mutex);
//read...
V(mutex);
V(empty);
}
/*wait signal形式*/
while(true){
wait(full);
wait(mutex);
//read...
signal(mutex);
signal(empty);
}
分析:
具有對稱性
先申請empty/full位,再申請緩衝區訪問許可權;先釋放mutex再釋放empty/full位
2. 讀者寫者問題 Readers and Writers Problem
要求:
- 多個讀者,只能read,不能write
- 多個寫者,既能read,也能write
- 允許多個reader同時讀
- 不允許reader和writer同時操作
- 不允許多個寫者同時操作
本質:保證一個writer程序必須與其他程序互斥地訪問共享物件
情況零:弱寫者優先(公平競爭)
要求:?
太簡單了(以後再補)
情況一:讀者優先
要求:
- 有讀者在讀,則其他讀者可讀,直到沒有讀者了,寫者才能寫
- 有寫者在寫,則其餘寫者和讀者等待
訊號量及其初始化
int readercount = 0;//共享變數,記錄當前讀者的數量 Semaphore mutex = 1;//readercount的鎖 Semaphore m = 1;//buffer的鎖
writer簡單程式碼描述
while(true){
wait(m);
//write
signal(m);
}
reader簡單程式碼描述
while(true){
wait(mutex);
readercount++;
if(readercount==1){
wait(m);
}
signal(mutex);
//read
wait(mutex);
readercount--;
if(readercount==0){
signal(m);
}
signal(mutex);
}
情況二:強寫者優先
要求:
- 寫者在寫,則其餘讀者和寫者等待;寫者寫完,優先釋放下一個寫者
- 讀者在讀,若無寫者等待,則其他讀者可讀
- 讀者在讀,若有寫者等待,則其他讀者等待
訊號量及其初始化
int readercount = 0;//共享變數,記錄當前讀者的數量
int writecount = 0;//共享變數,記錄當前寫者的數量
Semaphore mutex1 = 1;//readercount的鎖
Semaphore mutex2 = 1;//writecount的鎖
Semaphore read = 1;//buffer的讀鎖
semaphore write = 1;//buffer的寫鎖
Semaphore s = 1;//為了讓寫者優先
writer簡單程式碼實現
while(true){
wait(mutex2);
writecount++;
if(writecount==1){
wait(read);
}
signal(mutex2);
wait(write);
//write...
signal(write);
wait(mutex2);
writecount--;
if(writecount==0){
signal(read);
}
signal(mutex2);
}
reader簡單程式碼實現
while(true){
wait(s);
wait(read);
readercount++;
if(readercount==1){
wait(write);
}
signal(read);
signal(s);
//reading..
wait(mutex1);
readercount--;
if(readcounter==0){
signal(write);
}
signal(mutex1);
}
3.哲學家進餐問題 Dining-Philosophers Problem
要求:
- 有5個哲學家
- 哲學家只能吃飯或者思考,不能同時進行
- 哲學家只能拿兩根筷子才能吃飯
方案一:最多隻允許4個哲學家同時坐在桌子上
Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用
Semaphore seat=4;//可坐的位置
void philosppher(int i){
while(true){
think();
wait(seat);//申請座位
wait(chopstick[i]);
wait(chopstick[(i+1)%5]);
eat();
signal(chopstick[(i+1)%5]);
signal(chopstick[i]);
signal(seat);
}
}
方案二:非對稱方法,奇數哲學家拿左邊的筷子,偶數哲學家拿右邊的筷子
Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用
void philosppher(int i){
while(true){
think();
if(i&1){
wait(chopstick[i]);
wait(chopstick[(i+1)%5]);
eat();
signal(chopstick[(i+1)%5]);
signal(chopstick[i]);
}
else{
wait(chopstick[(i+1)%5]);
wait(chopstick[i]);
eat();
signal(chopstick[i]);
signal(chopstick[(i+1)%5]);
}
}
}
方案三:只有當兩邊都有筷子的時候才會同時拿起兩隻筷子
藉助AND型訊號量,其基本思想是:將程序在整個執行過程中需要的所有資源一次性全部分配給程序,待程序使用完後再一起釋放。只要尚有一個資源未能分配給程序,其他所有可能為之分配的資源也不分配給它。
Semaphore chopstick[5]={1,1,1,1,1};//筷子是否可用
void philosppher(int i){
while(true){
think();
Swait(chopstick[i],chopstick[(i+1)%5]);
eat();
Ssignal(chopstick[i],chopstick[(i+1)%5]);
}
}