操作系统 嗜睡的理发师 C++实现
介绍:
这是我的第一篇原创文档,希望可以帮助到大家,后续也会更新更多原创文档
说明:
三个mutex变量
room_mutex代表是否可以进入房间沙发(进程临界区)
1代表可以进入,0代表不可以进入
chair_mtex也是代表是否可以进入理发椅(也是临界资源)
1代表可以坐上沙发,0代表不能
boss_mutex代表理发师,也就是cpu(一次只能为一个顾客服务)
1代表可以给其他顾客服务,0代表不可以为其他顾客服务
同时这个变量也保证,结束理发一定要在开始理发之后,也就是线程的结束一定要在线程的执行之后。
这里面enter()代表创建线程,如果房间里面的资源都已经分配完,那就不能分配给进程资源,也就不能创建,只有有空间了才可以创建。分配的原则是,刚进来的顾客(线程)线程,如果椅子(处理机)空闲,就为他分配处理机(chair),但是这里面我写的是:分配之后不会立马执行,要等待cpu开始执行(就是hair_cut_begin()),当然这里也可以修改成,分配到处理机就立马执行。如果线程进入,处理机不是空闲,则要在等待队列(sofa等待)
hair_cut_begin()代表分配到的处理机线程的调度执行,调度的原则就是先到先得,在执行过程中,依然可以进入线程,其他线程就需要等待,这时boss_chair=0,代表正在执行
hair_cut_end(),这代表线程的完成,结束之后要调度,调度的原则就是先到先得,(我写的也可以不立马调度)这里要完成的话必须boss_chair=0,代表有线程在执行才可以结束,不能没有执行的线程就结束执行。
代码部分:
#include<iostream>
#include<string>
using namespace std;
#define maxsize 11 //这里定义沙发最多可以10人
class Customer
{
public:
string name; //定义顾客姓名
Customer() //无参数的构造函数
{
name = "None";
}
Customer(string n) //有参数的构造函数
{
name = n;
}
void pay() //顾客支付操作
{
cout<<"顾客"<<name<<"已付钱离开"<<endl;
}
};
// 定义循环队列 这个是上学期数据结构的知识
class SqQueue
{
public:
Customer data[maxsize];
int front;
int rear;
};
void InitQueue(SqQueue *&q) //初始化循环队列
{
q=new SqQueue [sizeof(SqQueue)];
q->front=0;
q->rear=0;
}
void DestroyQueue(SqQueue *&q) //销毁循环队列
{
delete(q);
}
bool QueueEmpty(SqQueue *q) //判断循环队列是否为空
{
return (q->front==q->rear);
}
bool QueueFull(SqQueue *q)
{
return ((q->rear+1)%maxsize==q->front);
}
bool enQueue(SqQueue *&q,Customer e) //进队
{
if((q->rear+1)%maxsize==q->front)
return false;
q->rear=(q->rear+1)%maxsize;
q->data[q->rear]=e;
return true;
}
bool deQueue(SqQueue *&q,Customer &e) //出队
{
if(QueueEmpty(q))
return false;
q->front=(q->front+1)%maxsize;
e=q->data[q->front];
return true;
}
class Room //定义理发店
{
public:
int room_size;
int customer_count; //顾客数量
SqQueue *sofa; //沙发
Customer chair; //理发椅子 1有人,0没人
bool chair_mutex; // 理发椅子上面的锁
bool room_mutex;
bool boss_mutex; //必须要先理发才能理发结束
Room();
~Room();
void infomation();
};
Room::Room()
{
room_size = maxsize;
customer_count = 0;
InitQueue(sofa);
chair = Customer();
chair_mutex = 1;
room_mutex = 1;
boss_mutex = 1;
}
Room::~Room()
{
cout<<"程序结束";
}
void enter(Room &room,Customer &p)
{
if(room.room_mutex == 1) //房间未满 下面是房间未满的几种情况
{
if(QueueEmpty(room.sofa)==1&&room.chair_mutex == 1) //此时沙发为空,椅子上也没有顾客
{
room.chair_mutex = 0;
room.chair = p;
cout<<"顾客"<<p.name<<"坐上椅子"<<endl<<endl;
cout<<"请选择操作:";
}
else if(QueueEmpty(room.sofa)==0&&room.chair_mutex == 1) //椅子上没人,沙发上也有人,新顾客仍然需要排队
{
enQueue(room.sofa,p);
cout<<"顾客"<<p.name<<"在沙发等待"<<endl;
cout<<"请选择操作"<<endl;
if(QueueFull(room.sofa)==1)
{
room.room_mutex=0;
}
}
else if(room.chair_mutex == 0) //此时椅子上有顾客,这时沙发一定未满,因为room_mutex=1
{
enQueue(room.sofa,p);
cout<<"顾客"<<p.name<<"在沙发等待"<<endl<<endl;
cout<<"请选择操作:";
if(QueueFull(room.sofa)==1)
{
room.room_mutex=0;
}
}
}
else
{
cout<<"房间已满,请在外等待或者离开"<<endl<<endl;
cout<<"请选择操作:";
}
}
void hair_cut_begin(Room &room)
{
if(room.chair_mutex==0) //椅子上有顾客了 理发师才能理发
{
room.boss_mutex = 0; //理发师资源被占用
cout<<"为顾客"<<room.chair.name<<"理发中"<<endl<<endl;
cout<<"请选择操作:";
}
else //没有顾客在椅子上
{
if(QueueEmpty(room.sofa)==0) //但如果沙发上有顾客,就给第一位顾客理发
{
deQueue(room.sofa,room.chair);
room.chair_mutex = 0;
room.room_mutex = 1;
room.boss_mutex = 0; //理发师资源被占用
}
else //如果沙发上没有顾客,理发师睡觉
{
room.boss_mutex = 1;
cout<<"没有顾客等待,理发师继续睡觉"<<endl<<endl;
cout<<"请选择操作:";
room.room_mutex = 1;
}
}
}
void hair_cut_end(Room &room)
{
if(room.chair_mutex==1||room.boss_mutex==1) //椅子上没有顾客,那就不能结束理发 ,理发师没有开始工作,也不能结束理发
{
cout<<"没有正在理发中的顾客"<<endl<<endl;
cout<<"请选择操作:";
}
else //椅子上有顾客,那可以理发完成
{
room.chair.pay();
room.customer_count++;
room.chair_mutex=1; //理发已经完成 下面就是唤醒等待队列里面的顾客
cout<<"输入1让下一位顾客坐上椅子,输入其他键让理发师休息:";
char a;
cin>>a;
if(a=='1')
{
if(QueueEmpty(room.sofa)) //没有进程,就停止工作了
{
cout<<"没有顾客等待,理发师继续睡觉"<<endl<<endl;
}
else //有的话唤醒等待最近的顾客
{
room.chair_mutex = 0;
deQueue(room.sofa,room.chair);
cout<<"顾客"<<room.chair.name<<"在椅子上等待"<<endl<<endl;
}
room.room_mutex = 1; //有人离开了,那room就可以进入
cout<<"输入下一步操作:";
}
else
{
cout<<"请选择操作:"<<endl;
}
}
room.boss_mutex=1; //!!!!!!!!!最后一定要设置boss_mutex让其他的顾客可以接受服务,同时保证理发结束,一定在理发开始动作完成之后执行
}
void Room::infomation() //打印表格
{
cout<<"当前椅子上有"<<1-chair_mutex<<"位顾客"<<endl;
cout<<"当前沙发上有"<<(sofa->rear - sofa->front + maxsize)%maxsize<<"位顾客"<<endl;
cout<<"当前已经为"<<customer_count<<"顾客服务过了"<<endl<<endl;
cout<<"请选择操作:";
}
int main()
{
cout<<"**************多线程嗜睡的理发师模拟**************"<<endl;
cout<<"输入0进行初始化"<<endl;
cout<<"输入1进入一名顾客"<<endl;
cout<<"输入2开始理发"<<endl;
cout<<"输入3理发结束"<<endl;
cout<<"输入4显示当前信息"<<endl;
cout<<"输入-1程序结束"<<endl<<endl;
int ans;
cin>>ans;
Room room;
int count=0;
while(ans!=-1)
{
switch(ans)
{
case 0:
cout<<"("<<count<<")"<<"初始化完成"<<endl<<endl;
cout<<"请选择操作:";
break;
case 1:
{
cout<<"("<<count<<")"<<"输入进入顾客的名字:";
string n;
cin>>n;
Customer customer(n); //定义一个顾客并初始化
enter(room,customer); //执行进店操作
break;
}
case 2:
cout<<"("<<count<<")";
hair_cut_begin(room);
break;
case 3:
cout<<"("<<count<<")";
hair_cut_end(room);
break;
case 4:
cout<<"("<<count<<")";
room.infomation();
break;
default:
cout<<"("<<count<<")"<<"输入正确的命令"<<endl<<endl;
}
cin>>ans;
if(ans==-1)
{
room.~Room();
}
count++;
}
}
运行结果
版权声明:本文为zzdxls原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。