例1:
在一个盒子里,混装了数量相等的黑白围棋子。现在用自动分拣系统把黑子、白子分开,设分拣系统有二个进程P1和P2,其中P1拣白子;P2拣黑子。
注意:
- 规定每个进程每次拣一子当一个进程在拣时,不允许另一个进程去拣。
- 当一个进程拣了一子时,必须让另一个进程去栋。
试写出两进程P1和P2能并发正确执行的程序。
分析:这是一个有序进行的程序,是同步关系。需设置两个信号量s1,s2来协调他们的活动。
设 s1=1; s2=0;
void white()
{
while(true)
{
wait(s1);
//拣白子
signal(s2);//发消息告知机器该拣黑子了
}
}
void black()
{
while(true)
{
wait(s2);
//拣黑子
signal(s1);//发消息告知机器该拣白子了
}
}
例2:有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。
semaphore empty = 100;// 记录空座位
semaphore mutex = 1;// 作为互斥的访问登记和注销操作
void reader()
{
while(true)
{
wait(empty);
wait(mutex);
// 此阶段为登记时期
signal(mutex);
// 正常阅读
wait(mutex);
// 离开,注销登记表
signal(mutex);
signal(empty);
}
例3:在一间酒吧里有三个音乐爱好者队列,第一个音乐爱好者只有随身听,第二个只有音乐磁带,第三个只有电池,而要听音乐就必须有随身听,音乐磁带和电池这三种物品。酒吧老板一次出售这三种物品中的任意两种,当一名音乐爱好者得到这三种物品并进入听完歌曲后,酒吧老板才能再一次出售这三种物品中任意两种,于是第二名音乐爱好者得到这三种物品。并开始听歌曲,全部买卖就这样进行下去。使用P,V操作正确解决这一买卖。
semaphore s = 1;
bool flag1,flag2,flag3 = true;// 标识是否有资源
semaphore s1 = 0,s2 = 0,s3 = 0;// 作为和爱好者进行同步的信号量
void boss()
{
while(true)
{
wait(s);//确认是否有顾客要买资源
if(flag2&flag3)
signal(s1);
else if(flag1&flag3)
signal(s2);
else
signal(s3);
}
}
void hobby1()
{
while(true)
{
wait(s1);
// 购买物品听乐曲
signal(s);// 发消息告知老板我已买好了所有物品
}
}
void hobby2()
{
while(true)
{
wait(s2);
// 购买物品听乐曲
signal(s);// 发消息告知老板我已买好了所有物品
}
}
void hobby3()
{
while(true)
{
wait(s3);
// 购买物品听乐曲
signal(s);// 发消息告知老板我已买好了所有物品
}