操作系统实验5 设备管理

【实验名称】设备管理

           

【实验目的】

1、理解设备管理的概念和任务。

2、掌握独占设备的分配、回收等主要算法的原理并编程实现。

 

【实验原理】

设备管理是指计算机系统对除CPU和内存以外的所有输入、输出设备的管理。设备管理不但要管理实际I/O操作的设备(如磁盘机、打印机),还要管理诸如设备控制器、DMA控制器、中断控制器、I/O处理机(通道)等支持设备。如何有效而又方便地管理好种类繁多的设备是设备管理的重要任务。

设备管理的目标:提高设备的利用率。为此,应尽量提高CPU与I/O设备之间的并行操作程度;为用户提供方便、统一的界面。所谓方便,是指用户能独立于具体设备的复杂物理特性之外而方便地使用设备。所谓统一,是指对不同的设备尽量使用统一的操作方式。

 

【实验内容】

实验内容:编写程序实现对独占设备的分配回收的模拟。

代码(详情见代码注释):

#include<iostream>
#include<string>
using namespace std;

//进程类
class PCB
{
public:
	//构造函数
	PCB(string n, string e, int nu)
	{
		name = n;
		equipment = e;
		num = nu;
		next = NULL;
	}
	string name;//进程名
	string equipment;//所需设备类
	int num;//设备相对号
	
	PCB* next;
};

//设备控制表
class DCT
{
public:
	DCT()
	{
		state = 0;
		work_now = new PCB("空", "", NULL);
		wait = NULL;
	}
	int state;//设备状态
	PCB* work_now;//当前运行的进程
	PCB* wait;//设备队列队首指针
};

//SDT节点
class SDT_node
{
public:
	SDT_node(string eq, string i)
	{
		equipment = eq;
		id = i;
	}
	string equipment;//设备类
	string id;//设备标识符
	DCT dct;//设备控制表
};

//SDT
class SDT
{
public:
	SDT(int i1,int i2,int i3,int i4)
	{
		Len[0] = i1; Len[1] = i2;
		Len[2] = i3; Len[3] = i4;
		for (int i = 0; i < i1; i++)
		{
			mouse[i] = new SDT_node("鼠标", "M" + to_string(i));
		}
		for (int i = 0; i < i2; i++)
		{
			keyboard[i] = new SDT_node("键盘", "K" + to_string(i));
		}
		for (int i = 0; i < i3; i++)
		{
			screen[i] = new SDT_node("显示屏", "S" + to_string(i));
		}
		for (int i = 0; i < i4; i++)
		{
			printer[i] = new SDT_node("打印机", "P" + to_string(i));
		}
	}

	void show();
	void show_class();
	void add(PCB *work);
	void del(string equipment, int num);
private:
	SDT_node* mouse[10];//鼠标
	SDT_node* keyboard[10];//键盘
	SDT_node* screen[10];//显示器
	SDT_node* printer[10];//打印机
	int Len[4];
};

//显示系统设备表(包括各阻塞队列)
void SDT::show()
{
	cout << "————————————————————————————————————————————" << endl;
	cout << "					系统设备表SDT" << endl;
	cout << "设备标识 ";
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < Len[i]; j++)
		{
			if (i == 0)
			{
				cout << mouse[j]->id << "\t";
			}
			else if (i == 1)
			{
				cout << keyboard[j]->id << "\t";
			}
			else if (i == 2)
			{
				cout << screen[j]->id << "\t";
			}
			else if (i == 3)
			{
				cout << printer[j]->id << "\t";
			}
		}
	}
	cout << endl;

	cout << "设备类   ";
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < Len[i]; j++)
		{
			if (i == 0)
			{
				cout << mouse[j]->equipment << "\t";
			}
			else if (i == 1)
			{
				cout << keyboard[j]->equipment << "\t";
			}
			else if (i == 2)
			{
				cout << screen[j]->equipment << "\t";
			}
			else if (i == 3)
			{
				cout << printer[j]->equipment << "\t";
			}
		}
	}
	cout << endl;

	cout << "设备状态 ";
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < Len[i]; j++)
		{
			if (i == 0)
			{
				cout << mouse[j]->dct.state << "\t";
			}
			else if (i == 1)
			{
				cout << keyboard[j]->dct.state << "\t";
			}
			else if (i == 2)
			{
				cout << screen[j]->dct.state << "\t";
			}
			else if (i == 3)
			{
				cout << printer[j]->dct.state << "\t";
			}
		}
	}
	cout << endl;
	cout << "当前运行 ";
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < Len[i]; j++)
		{
			if (i == 0)
			{
				cout << mouse[j]->dct.work_now->name << "\t";
			}
			else if (i == 1)
			{
				cout << keyboard[j]->dct.work_now->name << "\t";
			}
			else if (i == 2)
			{
				cout << screen[j]->dct.work_now->name << "\t";
			}
			else if (i == 3)
			{
				cout << printer[j]->dct.work_now->name << "\t";
			}
		}
	}
	cout << endl;
	
	//显示阻塞队列
	cout << "\n阻塞队列:" << endl;
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < Len[i]; j++)
		{
			if (i == 0)
			{
				cout << mouse[j]->id << ":";
				PCB *temp = mouse[j]->dct.wait;
				while (temp != NULL)
				{
					cout << " --> " << temp->name;
					temp = temp->next;
				}
				cout << endl;
			}
			else if (i == 1)
			{
				cout << keyboard[j]->id << ":";
				PCB *temp = keyboard[j]->dct.wait;
				while (temp != NULL)
				{
					cout << " --> " << temp->name;
					temp = temp->next;
				}
				cout << endl;
			}
			else if (i == 2)
			{
				cout << screen[j]->id << ":";
				PCB *temp = screen[j]->dct.wait;
				while (temp != NULL)
				{
					cout << " --> " << temp->name;
					temp = temp->next;
				}
				cout << endl;
			}
			else if (i == 3)
			{
				cout << printer[j]->id << ":";
				PCB *temp = printer[j]->dct.wait;
				while (temp != NULL)
				{
					cout << " --> " << temp->name;
					temp = temp->next;
				}
				cout << endl;
			}
		}
	}
	cout << endl;
	cout << "————————————————————————————————————————————\n" << endl;
}

//显示设备类表
void SDT::show_class()
{
	cout << "————————————————————" << endl;
	cout << "		设备类表" << endl;
	cout << "设备类   鼠标\t键盘\t显示屏\t打印机" << endl;
	cout << "设备数   " << Len[0] << "\t" << Len[1] << "\t" << Len[2] << "\t" << Len[3] << "\t" << endl;
	cout << "————————————————————\n" << endl;
}

//设备分配
void SDT::add(PCB *work)
{
	SDT_node** point;
	//找到对应设备类
	if (work->equipment == "鼠标")
	{
		point = mouse;
	}
	else if(work->equipment == "键盘")
	{
		point = keyboard;
	}
	else if (work->equipment == "显示屏")
	{
		point = screen;
	}
	else if (work->equipment == "打印机")
	{
		point = printer;
	}
	else
	{
		cout << "所需设备类不存在" << endl;
		return;
	}

	if (point[work->num]->dct.state == 0)
	{
		//若当前设备为空,则分配给该进程
		point[work->num]->dct.state = 1;
		point[work->num]->dct.work_now = work;
		cout << "设备分配成功,进程" << work->name << "正在运行" << endl;
	}
	else
	{
		//若设备不空闲则加入阻塞队列
		PCB *temp = point[work->num]->dct.wait;
		if (temp == NULL)
		{//如果阻塞队列为空
			point[work->num]->dct.wait = work;
		}
		else
		{//若阻塞队列不为空则找到队尾,并放入
			while (temp->next != NULL)
			{
				temp = temp->next;
			}
			temp->next = work;
		}
		cout << "该设备被占用,进程"<<work->name<<"被放入阻塞队列" << endl;
	}
}

//设备回收
void SDT::del(string equipment, int num)
{
	SDT_node** point;
	//找到对应设备类
	if (equipment == "鼠标")
	{
		point = mouse;
	}
	else if (equipment == "键盘")
	{
		point = keyboard;
	}
	else if (equipment == "显示屏")
	{
		point = screen;
	}
	else if (equipment == "打印机")
	{
		point = printer;
	}
	else
	{
		cout << "回收设备类不存在" << endl;
		return;
	}

	if (point[num]->dct.wait == NULL)
	{
		//阻塞队列为空
		point[num]->dct.state = 0;
		free(point[num]->dct.work_now);
		point[num]->dct.work_now = new PCB("空", "", NULL);
		cout << "设备" << point[num]->id << "被成功回收" << endl;
	}
	else
	{
		//阻塞队列不为空,调入等待进程
		free(point[num]->dct.work_now);
		cout << "设备" << point[num]->id << "被成功回收" << endl;
		cout << "设备" << point[num]->id << "阻塞队列存在进程" << endl;
		point[num]->dct.work_now = point[num]->dct.wait;
		point[num]->dct.wait = point[num]->dct.wait->next;
		cout << "进程" << point[num]->dct.work_now->name << "调入,设备被再次占用" << endl;
	}
}

int main()
{
	cout << "**************************" << endl;
	cout << "***     设备管理器     ***" << endl;
	cout << "*** 1.显示设备类表     ***" << endl;
	cout << "*** 2.显示系统设备表   ***" << endl;
	cout << "*** 3.设备分配         ***" << endl;
	cout << "*** 4.设备回收         ***" << endl;
	cout << "*** 5.退出             ***" << endl;
	cout << "**************************\n" << endl;

	//指定各类设备数量
	int a, b, c, d;
	cout << "请依次输入4类设备的数量:" << endl;
	cin >> a >> b >> c >> d;
	SDT My_SDT(a, b, c, d);
	
	int flag;
	while (true)
	{
		cout << "\n请选择功能:";
		cin >> flag;
		if (flag == 1)
		{
			//显示设备类表
			My_SDT.show_class();
		}
		else if (flag == 2)
		{
			//显示系统设备表
			My_SDT.show();
		}
		else if (flag == 3)
		{
			//设备分配
			string name;//进程名
			string equipment;//所需设备类
			int num;//设备相对号
			cout << "请输入进程名:";
			cin >> name;
			cout << "请输入所需设备类:";
			cin >> equipment;
			cout << "请输入设备相对号:";
			cin >> num;
			PCB *work = new PCB(name, equipment, num);

			My_SDT.add(work);

		}
		else if (flag == 4)
		{
			//设备回收
			string equipment;//设备类
			int num;//设备相对号
			cout << "请输入回收设备类:";
			cin >> equipment;
			cout << "请输入设备相对号:";
			cin >> num;

			My_SDT.del(equipment, num);
		}
		else if (flag == 5)
		{
			//退出
			cout << "成功退出!" << endl;
			break;
		}
	}
	return 0;
}

 

运行演示:

 

【小结或讨论】

这一次的实验是有一定难度的,我觉得困难主要是在实验的复杂程度上。这次我建了四个类来实现设备管理的功能:1、进程类PCB;2、设备控制表DCT;3、SDT节点SDT_node;4、系统设备表SDT。其中DCT、SDT_node、SDT是依次嵌套的,SDT使用了SDT_node,而SDT_node又使用了DCT。这里使用类的组合的原因是:SDT是整个系统的设备表,包括所有设备类的所有设备;而SDT_node是用来表示单个设备的,而每个设备都需要一个单独的设备控制表,所以我又建立了一个DCT类。由于这个类的组合比较复杂,类的初始化、修改的时候就比较复杂,而且这其中又涉及到类的指针、类的指针的指针,这就稍微有点烧脑,我也是认真整理好久思路,并在debug中不断改进。

我在实验的基本要求上稍微扩充了两点,其一是题目中各类设备数是固定的。我设计的就灵活一些,各类设备的数量是可以任意指定的,这一点也使得问题稍微复杂了些;其二就是进程的申请时我使用的是设备相对号,这一点虽然老师说了这比较复杂是不要求的,但是我觉得对于这个问题自己有解决思路,所以就仍然加入进来了。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值