操作系统 嗜睡的理发师 C++实现

操作系统 嗜睡的理发师 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版权协议,转载请附上原文出处链接和本声明。