小编刚写完一课程设计,现和大家分享下
PV实现同步与互斥
一 、需求分析
本程序的功能是:模拟车站售票厅内进程同步问题,售票厅任何时刻最多可容纳20名购票者进入,当售票厅中少于20名购票者时,厅外的购票者可立即进入,否则需要在外面等待。每个购票者可看成一个进程。
功能的互斥与同步的实现:
1. 当有乘客进入售票厅购票时,售票员不能下班(进程的互斥);
2. 当没有乘客购票时,则售票员下班(进程的互斥);
3. 乘客进入购票时,售票员给予售票(进程的同步)。
二、功能设计
本程序的设计思路和原理比较简单,由两个过程来实现售票员与乘客购票之间的过程。
1.售票员的操作过程
一开始时,设定当前售票厅内的人数为20,然后根据当天售票员到班情况来选择售票员上班的人数,由于过程和操作相似,故这里选择的售票员人数为0,1,2。
①当选择售票员为0时,则提示当天没有售票员上班,本售票站不进行售票操作;
②当选择的售票员为1时,则提示当天只有一个售票员上班,故每次只能对一个人进行售票操作;
③当选择的售票员为2时,则提示当天有两个售票员上班,故每次能同时对两个人进行售票操作。
2.乘客购票操作过程
①乘客先在售票厅外等候排队购票;②当提示售票厅内人数不足20人时,则按排队顺序进入售票厅内进行购票动作;③乘客购票完后则离开售票厅内。
3实现过程具体分析
① 由于程序中的售票厅最大只能容纳20个人,所以,当售票厅内的人数进入超过20时,则程序会提醒用户必须减少到人数小于等于20,不然程序不执行下去;
② 当进入售票厅内的人数与售票厅里原先的人数之和不足20时,会提醒用户,售票厅内还能容纳具体的人数;
③ 若在售票员处理完当前购票者的操作后,售票厅里人数为零;则售票员当天的售票任务结束,不再进行售票(这里只考虑这一理想情况)。
④ 当天如果选择的售票员上班人数为0时,则当天不进行售票操作。
三、功能实现过程
1.设置两个私有信号量:spys、ck,分别是售票员和乘客的。乘客的私有信号量初始值设为ck=0,售票员的初始值设为spys=1,以此来表示乘客的购票和售票员的售票操作的初始状态,当没有售票员时,则不能进行售票,当有乘客时,则售票员不能拒绝售票(这里排除票已售完的情况)。
1.实现流程图
2.售票员与乘客之间的过程
这里是实现P、V操作
Begin
Semaphore Spys,ck ;//设置售票员与乘客的私有信号量
Spys=1,ck=0;//初始化信号量
cobegin
int spy;//售票员人数
process 售票员 //售票员执行的过程
begin
switch(spy){ //选择售票员人数 ;
Case 0:goto S0;
Case 1: goto S1;
Case 2: goto S2;
}
S0: return 0;//无售票员上班,乘客无法购票;
End
S1:int P1( spys); //P操作
Hello( );//自定义的一个无返回值函数
售票操作;
售票结束;
提示下一位购票者;
Int V1(ck); //V操作
排队等候进入售票大厅内;
进入厅内排队等候购票;
购票后,离开售票大厅;
Goto S1;
End
S2:int P2( spys); //P操作
Hello( );//自定义的一个无返回值函数
售票操作;
售票结束;
提示下一位购票者;
Int V2(ck); //V操作
排队等候进入售票大厅内;
进入厅内排队等候购票;
购票后,离开售票大厅;
Goto S2;
End
四、程序结构
1.程序使用的头文件和宏
#include
#include
#include
#define MAX 20//厅内最大能容纳的人数
2.程序使用的函数和全局变量
int spys=1;//售票员的私有信号量
int spy;//选择售票员的人数,最多只能有两个
int ck=0;//厅内购票者私有信号量
int n=MAX;
int x;//每次进入售票厅内的人数
int P1();//定义P操作函数,一个售票员执行的过程
int P2();//定义p操作,两个售票员执行该过程
int j=0;//人多时,减少的人数
int V1();//V操作函数,一个售票窗口时购买者执行的过程
int V2();//V操作函数,两个售票窗口时购买者执行的过程
void Hello();//输出客套语句
void Introduce();//本售票站人员介绍
3.主函数
int main()
{
Introduce();
printf("请输入今天上班的售票员人数:(最多2位): ");
scanf("%d",&spy);
switch(spy){
case 0:{printf("sorry!由于今天假日,所以售票员不上班,请各位乘客改乘其他交通工具! ");break;}
case 1:{ printf("今天就一个窗口售票哦!请乘客们排成一队!谢谢合作! ");P1();break;}
case 2:{printf("今天有两个售票窗口啦!请乘客们按顺序排成两队!谢谢合作 ");P2();break;}
default:{printf("本站员工有限,没有多余员工哦!");break;}
}
return 0;
}
4.售票员操作过程
int P1() //一个售票窗口时执行的过程
{
spys--;//p操作
if(spys==0)
{
Sleep(4000);
printf("20B506客运站欢迎各位乘客来乘坐本公司的汽车!祝你旅途愉快! ");
Sleep(4000);
n--;
Hello();
Sleep(5000);
printf("当前购买者完成购票,请下一位购票者就绪 ");
Sleep(4000);
printf("当前售票厅内人数为%d ",n);
ck++;//v操作
}
else
spys++;
V1();
return 0;
}
5.乘客购票操作过程
int V1()//顾客的执行过程
{
ck--;//相当于p操作
if(ck==0)
{
printf("请厅外的购票者排按顺序进入购票厅内(最多能进入人数为:%d): ",MAX-n);
scanf("%d",&x);
n=n+x;
printf("售票厅内人数为%d",n);
if(n>MAX){
printf("人数太多了,站不住脚呀!请出去一些人到售票厅外等候吧! ");
printf("请输入出去的人数: ");
scanf("%d",&j);
while(j>n-MAX){
printf("还可以再进来些人哦!!");
printf("请在厅外等候的乘客进入售票厅内吧: ");
scanf("%d",&j);
}
n=n-j;
printf("售票厅内人数为%d",n);
}
if(n==0) {
printf("可以下班了,售票员们,你们辛苦了 ");
return 0;
}
}
//printf(" 厅内排队人数为%d,请厅外购票者们耐心等候,谢谢合作 ",n-1);
if(n>=20)
printf("已经达到最大人数,请厅外的乘客耐心等候!谢谢合作 ");
else
printf(",本售票厅内可容纳最多20人数!,还可再进入%d人。 ",MAX-n);
Sleep(4000);
spys++;//执行v操作
P1();
return 0;
}
6.Hello函数
void Hello()//say hello
{
printf("售票厅内能容纳最多的人数为20人,请乘客们按顺序在厅外等候!谢谢合作! ");
}
void Introduce()
{
system("color 4e");
printf("------------------------------欢迎来到20B506客运站----------- ");
printf("-----站长:雅布珊----- ");
printf("----------副站长:vivien---- ");
printf("--------------售票员甲:胖哥------ ");
printf("-------------------售票员乙:忠哥----- ");
printf("----------------------------------我们的服务就是最好的承诺! ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
printf(" ");
}