目录
摘要………………………………………………...........2
正文
1. 设计思想…………………………………………..3
2. 各模块的伪码算法………………………………..5
3. 函数的调用关系图………………………………..9
4. 测试结果………………………………………….11
设计总结……………………………………………......12
参考文献……………………………………………......13
致谢…………………………………………………......14
附录:部分源程序代码..................................................15
摘要
理发师问题是一个利用信号量进行 PV 操作的经典问题。设计程
序实现此问题,要使得理发师的活动与顾客的活动得到各自真实的模
拟。所执行的程序应体现:理发师在没有顾客的时候去睡觉,有顾客
则工作;顾客在理发师工作时坐下等待,无座时离开,直至等到理发
师为自己理发。
关键字:理发师,顾客,PV 操作。
2
1.设计思想
依题意,程序的活动单元有理发师,顾客到来这两个。其中,理
发师有活动有理发和睡觉两个事件;顾客有到来,等待,离去三个事件。
店里有固定的椅子数,上面坐着等待的顾客,顾客在到来这个事件时,
需判断有没空闲的椅子,理发师决定要理发或睡觉时,也要判断椅子
上有没顾客,所以,椅子(即上面的顾客数)是需要互斥访问的,用
mutex 标识信号量,初值为 1。理发师与顾客之间是同步关系,
customer
//该信号量表示等待的顾客的人数,初值为 0
position //该信号量表示剩余的椅子数,初值为 n
理发师:
P(customer)
V(position)
理发师理发,释放一个椅子
顾客:
P(position)
V(customer)
顾客等待
执行过程如下:
(1)开始时,没顾客, customer=0,理发师“阻塞”, position=n
3
(2)一个顾客来,然后 position 减一个,等待, customer 加一个,
顾客“进程”完毕,等待新的进程来到
(3)理发师:当 customer>0 时,执行理发动作,然后 position
加一个。
注意:每个进程都是自己循环执行的,比如当理发师“进程”执
行完最后一个 V 原语后就再执行第一个 P 原语,顾客“进程”也一样。
2.各模块的伪码算法
(1).第一个顾客到来算法:
4
void get_in()
{
lifa_chair=lifa_chair+1;
cout<<"wakeup the barber!\n";
}//Firstcome;
(2).顾客等待算法:
void wait()
{
count=count+1;
cout<<"no barbers now,please waiting.\n";
}//wait;
(3).顾客离开算法:
void get_out()
{
cout<<"all seats taken,go!\n";
}//leave;
(4).理发师为下一顾客服务算法:
void next()
{
count=count-1;
5
//lifa_char=1;
cout<<"there sits customers,go on!\n";
}//nextcustomer;
(5).理发师去理发算法:
void sleep()
{
cout<<"nobody is waitting,go to sleep!\n";
lifa_chair=0;
}//gotosleep;
(6).主函数:
int main()
{
cout<<"1.A customer comes!;\n2.finish one,get the
money!\n3.exit\n";
char a;
cin>>a;
//给出功能选择,提供模拟的状态
while(a=='1'||a=='2')
{
if(a=='1')
6
{
if(lifa_chair==0)
{
}
get_in();
else
{
if(lifa_chair==1&&count<5)
{
}
wait();
else if(lifa_chair==1&&count==5)
get_out();
{
}
}
}//顾客到来,以lifa_chair作为互斥信号量区分顾客等待与
理发的状态
if(a=='2')
{
if(count>0)
{
7
next();
}
else
{
}
sleep();
}//理发师完成一个顾客,以count作为等待数控制理发师继续
工作还是睡觉的状态。
cout<<"1.A customer comes!;\n2.finish one,get the
money!\n3.exit\n";
cin>>a;
}//循环执行
return 0;
}
3.函数的调用关系图
8