采用P、V操作的同步算法如下:
semaphore SAB=1;//A、B的资源信号量,同时又是它们的互斥信号量
semaphore SC=0;//C的资源信号量(用于与A同步)
semaphore SD=0;//D的资源信号量(用于与B同步)
begin
parbegin
process A://进程A的算法描述{
while(true){
取一个苹果;
wait(SAB);//测试盘子是否为空
将一苹果放入盘中;
signal(SC)//通知C盘中已有苹果(可能唤醒C)}}
process C:{
while(true){
wait(SC);//测试盘子是否有苹果
从盘中取出苹果;signal(SAB);//通知A(或B)盘子已经空(可能唤醒A或B)
消费该苹果;}}
process B://进程B的算法描述{
while(true){
取一个梨子;
wait(SAB);//测试盘子是否为空
将一梨子放入盘中;
signal(SD)//通知D盘中已有梨子(可能唤醒D)}}
process D:{
while(true){
wait(SD);//测试盘子是否有梨子
从盘中取出梨子;signal(SAB);//通知A(或B)盘子已经空(可能唤醒A或B)
消费该梨子;}}
parend
end
采用管程的同步算法如下:
首先定义管程MPC,该管程可描述如下:
type MPC=monitor
var flag: integer;//flag=0:盘中无水果;=1盘中有苹果;=2盘中有梨子
empty: condition;//用于A或B等待空盘子
W: array[1..2] of condition //W[1]用于等待苹果,W[2]用于等待梨子
procedure entry put(integer k)
begin
if flag>0 then empty.wait;//生产者A或B进程阻塞
flag=k;
放一k号水果入盘中;//设1号水果为苹果,2号水果为梨子if W[k].queue then full.signal;//若有等待k号水果者,则唤醒之
end
procedure entry get(integer k)
begin
if flag<k then W[k].wait;//消费者C或D进程阻塞
从盘中取k号水果;
flag :=0;if empty.queue then empty.signal;//若等待队列非空,则唤醒队首的一个生产者进程
end
begin
flag :=0;//初始化内部数据
end
A、B、C、D四个进程的同步算法可描述如下:
parbegin
Process A
begin
任取一个苹果;
MPC.put(1);
end
Process B
begin
任取一个梨子;
MPC.put(2);
end
Process C
begin
MPC.get(1);
吃苹果;
end
Process D
begin
MPC.get(2);
吃梨子;
end
parend