- 某寺庙中有若干个老和尚和小和尚,并有一个水缸能储存10桶水,小和尚每天从寺庙的水井中打水入缸供老和尚饮用。寺庙中有3个水桶,小和尚从井中打水时,由于水井口窄,每次只能使用1个水桶;每次打水入缸和从缸中取水仅为1桶,且不可同时进行。试用信号量和P、V操作,给出小和尚从井中打水和老和尚从缸中取水的算法描述。
/* 互斥信号量mutex1代表互斥使用水井,
互斥信号量mutex2代表互斥使用水缸,
Count 代表水桶的使用情况
Empty代表可提水入缸的桶数,
Full代表可从水缸提水的桶数。
*/
Var mutex1, mutex2, empty, full, count: semaphore;
mutex1:=1; mutex2:=1;
empty:=10; full:=0; count:=3;
Process 小和尚:
begin
While(1):
P(empty);/是否需要打水
P(count);/是否有桶
P(mutex1);/水井是否可用
从水井打水
V(mutex1);/离开水井
P(mutex2);/水缸是否可用
将水倒入缸中
V(mutex2);/离开水缸
V(full);/增加水缸中的水的信号量值
V(count);/释放水桶
end
Process 老和尚:
begin
While(老和尚渴的时候):
P(full);/水缸是否有水
P(count);/是否有桶
P(mutex2);/水缸是否可用
从水缸中取水喝
V(mutex2);/离开水缸
P(empty);/增加水缸中的可入缸的桶数的信号量值
V(count);/释放水桶
end
- 一个主修动物行为学、辅修计算机科学的学生参加了一个课题,调查花果山的猴子是否能被教会理解死锁。他找了一处峡谷,横跨峡谷拉了一条南北方向的绳索,这样猴子就可以攀着绳索越过峡谷。只要它们朝着同样的方向,同一时刻可以有多只猴子通过。但是如果在相反的方向上同时有猴子通过,则会发生死锁(这些猴子将被卡在绳索中间,假设这些猴子无法在绳索上从另一只猴子身上翻过去)。如果一只猴子想越过峡谷,它必须看当前是否有其他猴子在逆向通行。请使用信号量机制解决该问题。
/* 互斥信号量mutex1代表互斥使用绳索,
互斥信号量mutex2代表往南走的猴子使用时的保护临界区,
互斥信号量mutex3代表往北走的猴子使用时的保护临界区,
scount,ncount分别代表往南往北走的猴子的个数。
*/
Var mutex1, mutex2, mutex3, scount, ncount: semaphore;
mutex1:=1; mutex2:=1; mutex3 = 1;scount:=ncount:=0;
Process 南行猴子:
begin
While(有猴子想南行的时候):
P(mutex2);/保护临界区
if(scount == 0)
P(mutex1);/等待绳索资源
scount++;
V(mutex2);/ 保护临界区
猴子通过绳索过桥
P(mutex2);/保护临界区
scount—
if(scount == 0)
V(mutex1);/释放绳索资源
V(mutex2); /保护临界区
end
Process 北猴子:
begin
While(有猴子想北行的时候):
P(mutex3);/保护临界区
if(ncount == 0)
P(mutex1);/等待绳索资源
ncount++;
V(mutex3);/ 保护临界区
猴子通过绳索过桥
P(mutex3);/保护临界区
ncount—
if(ncount == 0)
V(mutex1);/释放绳索资源
V(mutex3); /保护临界区
end
- 有A、B两人通过信箱进行辩论,每个人都从自己的信箱中取得对方的问题。将答案和向对方提出的新问题组成一个邮件放入对方的邮箱中。假设A的信箱最多放M个邮件,B的信箱最多放N个邮件。初始时A的信箱中有x个邮件(0<x<M),B的信箱中有y个邮件(0<y<N)。辩论者每取出一个邮件,邮件数减1。A和B两人的操作过程描述如下:
CoBegin
A{
while(TRUE) {
从A的信箱中取出一个邮件;
回答问题并提出一个新问题;
将新邮件放入B的信箱;
}
} B{
while(TRUE) {
从B的信箱中取出一个邮件;
回答问题并提出一个新问题;
将新邮件放入A的信箱;
}
}
CoEnd
当信箱不为空时,辩论者才能从信箱中取邮件,否则等待。当信箱不满时,辩论者才能将新邮件放入信箱,否则等待。请添加必要的信号量和P、V(或wait、signal)操作,以实现上述过程的同步。要求写出完整过程,并说明信号量的含义和初值。
/* 互斥信号量mutex1代表互斥使用A信箱,
互斥信号量mutex2代表互斥使用B信箱,
full1,full2分别代表往A、B信箱中有多少封信。
empty1,empty2分别代表往A、B信箱中还可放多少封信。
*/
Var mutex1, mutex2, full1,full2, empty1,empty2: semaphore;
mutex1:=1; mutex2:=1; full1:=x,full2:=y, empty1: =M-x,
empty2:= N-y;
Process A信箱:
begin
while(true)
{
P(full1);/信箱A中是否有信
P(mutex1);/信箱A是否被占用
读取信件;
V(mutex1);/ 释放信箱
V(empty1); /A信箱可多放一封信
回答问题并提问后;
P(empty2);/信箱B是否可放信件
P(mutex2);/信箱B是否被占用
将信件放入B中
V(mutex2);/释放B信箱
V(full2);/信箱B中多了一封信
end
}
Process B信箱:
begin
while(true)
{
P(full2);/信箱B中是否有信
P(mutex2);/信箱B是否被占用
读取信件;
V(mutex2);/ 释放信箱
V(empty2); /B信箱可多放一封信
回答问题并提问后;
P(empty1);/信箱A是否可放信件
P(mutex1);/信箱A是否被占用
将信件放入A中
V(mutex1);/释放A信箱
V(full1);/信箱A中多了一封信
end
}