操作系统 嗜睡的理发师 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++;	
	} 
}

运行结果

  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: 这段文字似乎是一个问题,内容是关于一个理发店的:一个理发店由一个由n张沙发发的等候室和一个放有一张理发椅的理发室组成。没有顾客要理发时,理发师便去睡觉。当一个顾客走进理发店时,如果所有的沙发都已被占用,他便离开理发店;否则,理发师便去理发。问:当一个顾客进入理发店时,如果所有的沙发都已被占用,他便离开理发店吗?如果理发店正在为一个顾客理发,他离开理发店吗? ### 回答2: 题意理解 这道题目讲述了一个嗜睡理发师的日常工作情景,他总是在没有客人理发的时候就会去睡觉。然而当有一个顾客来到理发店时,如果等候室所有的沙发都已经被占用,那么这个顾客就会离开理发店,否则这个顾客就可以进入理发室理发。我们需要设计一个程序,使得能够模拟出这个场景,求解在一个具有n张沙发的等候室中,理发师的睡觉时间以及顾客离开理发店的机率。 问题分析 这个问题应该可以采用概率论知识来解决。考虑到顾客来店的时刻服从泊松过程,我们可以借助泊松过程的性质来确定每个顾客来店的时间。当一个顾客来店时,如果等候室还有空余的沙发,他就可以进入等候室等待理发;否则他就会离开理发店。 在理发师的睡觉问题上,我们考虑到理发师在每个顾客到来时都会被吵醒,所以他的睡眠会被打断,而睡眠状态的中断时间服从指数分布。当理发师被吵醒后,他就会去理发室接待客人;当他没有人理发时,他就会继续睡觉,等待下一个客人的到来。 问题求解 我们可以模拟出一个具有$n$张沙发的等候室和一个理发室的状态,以此来推导出理发师睡眠时间和顾客离开理发店的概率。 首先,我们设等候室中还有$k$张沙发可以供客人等待。当一个顾客来店时,如果等候室已经没有沙发了,那么他就会离开理发店;否则他就会进入等候室等待理发。 然后,我们考虑到理发师睡眠状态可能会被客人的到来所中断。当理发师被吵醒时,他就会去理发室接待客人;如果他没有客人,他就可以继续睡觉。由于睡眠状态的中断时间服从指数分布,所以我们可以采用指数分布对此进行建模。设理发师在任意时刻进入沉睡状态的概率为$p$,则在$t$时刻内他进入沉睡状态的概率为$p(1-p)^t$。我们可以通过这个概率来计算出理发师在$t$时刻内处于沉睡状态的概率,以此来推导出理发师睡眠时间。 最后,我们可以通过求解概率公式或者数值解的方法,来计算出顾客离开理发店的概率。 总结 以上所述即为嗜睡理发师问题的解答思路和方法。我们需要综合运用概率论和数学等相关知识,来模拟出这个场景并求解出问题的答案。同时,我们还需要注意对于模型的精度和数据要求,以使得研究结果更加准确可靠。 ### 回答3: 这是经典的计算机科学问题,被称为“嗜睡理发师问题”。它涉及到一个理发店的运营,其中有一位理发师和一个等候室。问题是,在没有顾客要理发的时候,理发师会睡觉,但当有顾客到来时,他必须待在理发室内为其服务。如果没有沙发空着,顾客就会离开。 为了解决这个问题,我们可以使用线程同步的方法和一个计数器来跟踪等候室中有多少人。例如,我们可以使用一个计数器和锁来确保同一时间只有一个顾客能够进入等候室,从而避免竞争条件。此外,我们可以使用条件变量来控制顾客和理发师之间的协调,从而避免死锁问题。 解决此问题的一种方法是使用两个计数器:一个表示等待的人数,另一个表示当前正在等待理发师的人数。一开始,等待计数器为0,理发师计数器为0。当有人进入理发店时,如果没有人在等待,理发师必须开始为其服务,并将等待计数器增加1。如果有人在等待,理发师会直接为其服务,并将等待计数器减少1。当理发师完成工作,如果没有人在等待,他会继续睡觉。如果有人在等待,他会继续为其服务,直到等待计数器再次为0。 通过这种方式,我们可以确保顾客和理发师之间的协调,并在需要时唤醒等待线程,从而避免资源浪费和死锁问题。这个问题很好地说明了使用线程同步的重要性,同时也让我们更好地了解了多线程编程的难点。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值