@1405010304geshuaishuai
2016-05-13T09:37:25.000000Z
字数 2577
阅读 675
理发师通信
通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题。
理发店理有一位理发师、一把理发椅和5把供等候理发的顾客坐的椅子。如果没有顾客,理发师便在理发椅上睡觉。一个顾客到来时,它必须叫醒理发师。如果理发师正在理发时又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。
图 6-1 barber 进程
图 6-2 customer 进程
题目中要求描述理发师和顾客的行为,因此需要两类进程Barber()和Customer()分别描述理发师和顾客的行为。当理发师看报时顾客近来需要唤醒理发师为其理发,当有顾客时理发师为其理发,没有的时候理发师休息,因此理发师和顾客之间是同步的关系,由于每次理发师只能为一个人理发,且可供等侯的椅子有限只有n个,即理发师和椅子是临界资源,所以顾客之间是互斥的关系。故引入3个信号量和一个控制变量:1)控制变量waiting用来记录等候理发的顾客数,初值均为0;2)信号量customers用来记录等候理发的顾客数,并用作阻塞理发师进程,初值为0;3)信号量barbers用来记录正在等候顾客的理发师数,并用作阻塞顾客进程,初值为0;4)信号量mutex用于互斥,初值为1
#include<windows.h>#include "iostream.h"#include "math.h"#define random (rand()*10000)/RAND_MAX //定义一个随机函数来产生顾客,并且使两个顾客间的时间少于10秒int long waiting(0); //正在等待的顾客的数目int chairs; //椅子的总数目char close_door; //关门int count(0); //顾客的号码数int finish(0); //理发完毕的顾客数目DWORD a;void cutchair(){Sleep(10000);cout<<"理发完成!"<<endl; //理发师理发函数,用时10秒}void gethaircut(){Sleep(10001); //顾客被理发的函数cout<<"第"<<finish<<"个顾客理发完毕,离开"<<endl;}HANDLE Mutex=CreateMutex(NULL,FALSE,"Mutex"); //用来实现进程的互斥HANDLE barbers=CreateSemaphore(NULL,1,1,"barbers"); //定义信号量来进行线程间的同步HANDLE customers=CreateSemaphore(NULL,0,3,"customers");DWORD WINAPI customer(LPVOID pParm2) //顾客的线程{WaitForSingleObject(Mutex,INFINITE); //p(mutex)进入临近区count++; //来的是第几名顾客cout<<"第"<<count<<"个顾客来了"<<endl;if(waiting<chairs) //如果还有椅子可以坐{if(waiting!=0){cout<<"此时有"<<waiting<<"个人在等待理发"<<endl;}elsecout<<"没有人在等待"<<endl;//输出有多少人在等待waiting++;cout<<"还有"<<chairs-waiting+1<<"个座位"<<endl;cout<<"有座位,顾客已经坐下"<<endl;ReleaseSemaphore(customers,1,NULL); //释放信号量ResumeThread(customers); //唤醒理发师进程ReleaseMutex(Mutex); //释放互斥量,以便其他线程使用WaitForSingleObject(barbers,INFINITE); //等待理发gethaircut(); //理发并离开}else{cout<<"座位已满,第"<<count<<"个顾客离开"<<endl; //没有椅子,顾客直接离开ReleaseMutex(Mutex);}return 0;}DWORD WINAPI barber(LPVOID pPam1) //理发师线程{while(true) //一直执行{WaitForSingleObject(customers,INFINITE); //p(customers),等待顾客WaitForSingleObject(Mutex,INFINITE); //等待互斥量waiting--;//等待的人数减一ReleaseSemaphore(barbers,1,NULL); //释放信号量ResumeThread(barbers);//唤醒顾客进程ReleaseMutex(Mutex); //v(mutex)cutchair();//理发finish++; //理发完毕的顾客数目加一}return 0;}int main(){cout<<"请输入椅子的总数目:";cin>>chairs;cout<<"理发店共有"<<chairs<<"把椅子"<<endl;HANDLE hThread1;HANDLE hThread2;hThread2=CreateThread(NULL,0,barber,NULL,0,NULL); //产生一个理发师进程while(close_door!='y'){Sleep(random);//顾客随机到来hThread1=CreateThread(NULL,0,customer,NULL,a,NULL);cout<<endl<<"**********欢迎光临**********"<<endl;if(finish>=10&&waiting==0)//如果完成数超过10并且没有人等待{cout<<"已经为"<<finish<<"个顾客理发了,要关门下班吗?"<<endl;cin>>close_door;return close_door;}}if(close_door=='y'){cout<<"**********暂停营业*********"<<endl;return 0;}}
实验截图如图6-3:
图 6-3 运行结果