@1405010304geshuaishuai
2016-05-13T09:37:25.000000Z
字数 2577
阅读 541
理发师通信
通过生产者和消费者问题(理发店问题)的设计和调试,使学生掌握进程同步的工作原理,利用信号量的原理和机制去解决同步问题。
理发店理有一位理发师、一把理发椅和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;
}
else
cout<<"没有人在等待"<<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 运行结果