小編剛寫完一課程設計,現和大家分享下
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位):\n");
scanf("%d",&spy);
switch(spy){
case 0:{printf("sorry!由於今天假日,所以售票員不上班,請各位乘客改乘其他交通工具!\n");break;}
case 1:{ printf("今天就一個窗口售票哦!請乘客們排成一隊!謝謝合作!\n");P1();break;}
case 2:{printf("今天有兩個售票窗口啦!請乘客們按順序排成兩隊!謝謝合作\n");P2();break;}
default:{printf("本站員工有限,沒有多餘員工哦!");break;}
}
return 0;
}
4.售票員操作過程
int P1() //一個售票窗口時執行的過程
{
spys--;//p操作
if(spys==0)
{
Sleep(4000);
printf("20B506客運站歡迎各位乘客來乘坐本公司的汽車!祝你旅途愉快!\n");
Sleep(4000);
n--;
Hello();
Sleep(5000);
printf("當前購買者完成購票,請下一位購票者就緒\n");
Sleep(4000);
printf("當前售票廳內人數為%d\n",n);
ck++;//v操作
}
else
spys++;
V1();
return 0;
}
5.乘客購票操作過程
int V1()//顧客的執行過程
{
ck--;//相當於p操作
if(ck==0)
{
printf("請廳外的購票者排按順序進入購票廳內(最多能進入人數為:%d):\n",MAX-n);
scanf("%d",&x);
n=n+x;
printf("售票廳內人數為%d",n);
if(n>MAX){
printf("人數太多了,站不住腳呀!請出去一些人到售票廳外等候吧!\n");
printf("請輸入出去的人數:\n");
scanf("%d",&j);
while(j>n-MAX){
printf("還可以再進來些人哦!!");
printf("請在廳外等候的乘客進入售票廳內吧:\n");
scanf("%d",&j);
}
n=n-j;
printf("售票廳內人數為%d",n);
}
if(n==0) {
printf("可以下班了,售票員們,你們辛苦了\n");
return 0;
}
}
//printf("\n廳內排隊人數為%d,請廳外購票者們耐心等候,謝謝合作\n",n-1);
if(n>=20)
printf("已經達到最大人數,請廳外的乘客耐心等候!謝謝合作\n");
else
printf(",本售票廳內可容納最多20人數!,還可再進入%d人。\n",MAX-n);
Sleep(4000);
spys++;//執行v操作
P1();
return 0;
}
6.Hello函數
void Hello()//say hello
{
printf("售票廳內能容納最多的人數為20人,請乘客們按順序在廳外等候!謝謝合作!\n");
}
void Introduce()
{
system("color 4e");
printf("------------------------------歡迎來到20B506客運站-----------\n");
printf("-----站長:雅布珊-----\n");
printf("----------副站長:vivien----\n");
printf("--------------售票員甲:胖哥------\n");
printf("-------------------售票員乙:忠哥-----\n");
printf("----------------------------------我們的服務就是最好的承諾!\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
printf("\n");
}