-
实验目的
1. 对理论课中学习的设备管理和文件管理当中的概念做进一步的理解;
2. 明白设备管理的主要任务;
3. 了解设备管理任务的主要实现方法;
4. 通过编程,学会独占设备的分配,回收等主要算法的原理。
-
实验原理
1.独占设备通常使用静态分配方式,即在作业执行准备期间分配所需设备,作业执行期间设备归该作业占用,直到作业执行结束才归还给系统。
2.设备分配通过“设备分配表”来实现,该表记录独占设备类型、数量及分配情况。
3.设备分配表由“设备类表”和“设备表”两部分组成。
(1)“设备类表”记录系统中各类设备的总数、当前空闲设备数和设备表中的起始地址。
(2)“设备表”记录每一台设备的绝对号、使用情况、分配状态、占用作业名和相对号。
4.在操作系统当中,对于独占设备,通常使用静态分配方式,就是在一个作业执行准备其间,将该作业所需要使用到的设备分配给作业,在该作业执行其间这个设备归该作业占用,直到作业执行结束才归还给系统。此实验中,就要通过模拟方法来实现简单的独占设备的分配和回收。
5.在操作系统中,通过设置”设备分配表” ,用来记录计算机系统所配置的独占设备的类型,数量以及分配情况等。为了实现设备分配,回收过程的独立性,设备分配表一般由”设备类表”和”设备表”两部分组成。
-
设计要求
1.模拟独占设备的分配和回收。编写程序,由必要的数据结构、主函数、设备分配函数和设备回收函数构成。实现对独占设备的分配与回收的模拟。
2.设计“设备分配表”,包括“设备类表”和“设备表”。
3.“设备类表”记录设备类别、总数、空闲设备数和起始地址。
4.“设备表”记录每台设备的绝对号、使用情况、分配状态、占用作业名和相对号。
5.设备表中用"1"表示设备好,用"0"表示设备坏;用"1"表示设备已分配,用"0"表示设备空闲。
6.编写程序,包括数据结构、主函数、设备分配函数和设备回收函数。
7.设备分配时,输入作业名、设备类名和相对号。
8.设备回收时,输入作业名和设备类名。
-
实验所用函数
1.设备类表查询:查询设备类表,获取设备类别的相关信息。
2.设备表查询:在设备表中查找特定类别的设备,并确定其状态。
3.设备分配(int allocate(char l[],char type[],int mm)//设备分配函数):
根据作业请求,查找并分配“好的且未分配”的设备给作业。
4.设备状态修改:修改设备类表和设备表中的设备状态,记录分配信息。
5.设备回收(int reclaim(char l[],char type[])//设备回收函数):
作业完成后,将设备状态设置为“未分配”,并更新可使用数量。
-
实验代码
/*独占设备的分配和回收模拟*/
#include <bits/stdc++.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<pthread.h>
#include<semaphore.h>
#include<iomanip>
using namespace std;
std::string expected_username="wx123";
std::string expected_password="123456";
const int n=4,m=10; //假设系统有4类设备 10个设备
//四类设备分别是 输入机 打印机 磁盘机 磁带机
//定义结构体 相当于设备表
struct node1
{
char type[10]; //设备类名
int count ; //拥有设备台数
int remain; //现存的可用设备台数
int address; //该类设备在设备表中的起始地址
}equiptype[n]; //设备类表定义,假定系统有n个设备类型
struct node2
{
int number; //设备绝对号(也就是设备的物理名)
int status; //设备好坏状态 1-好、0-坏
int remain; //设备是否已分配 1-已分配、0-空闲
char jobname[4];//占有设备的作业名
int lnumber; //设备相对号
}equipment[m]; //设备表定义,假定系统有m个设备
int allocate(char l[],char type[],int mm)//设备分配函数
{
int i=0,t,p; /* 查询该类设备 */
while(i<n&&strcmp(equiptype[i].type,type)!=0) i++;
if(i>=n) /* 没有找到该类设备 */
{
printf(" 无该类设备 ,设备分配失败 !");
return(false);
}
else {
printf(" 存在该类设备! ");
}
if(equiptype[i].remain<1) /* 所需设备现存可用台数不足 */
{
printf(" 该类设备不足,分配失败 !");
return(false);
}
else {
printf(" 该类设备充足! ");
}
t=equiptype[i].address; /* 取出该类设备在设备表中的起始地址 */
while(!(equipment[t].status==1 && equipment[t].remain==0))
t++; /* 填写作业名、 相对号, 状态改为已分配*/
equiptype[i].remain--;
equipment[t].remain = 1;
strcpy(equipment[t].jobname,l);
equipment[t].lnumber = p;
printf(" 分配成功! ");
}
int reclaim(char l[],char type[])//设备回收函数
{
int i=0,t,j,k,z;
while(i<n&&strcmp(equiptype[i].type,type)!=0) i++;
if(i>=n) /* 没有找到该类设备*/
{
printf(" 无该类设备 ,设备回收失败 !");
return(false);
}
else printf(" 存在该类设备! ");
t = equiptype[i].address; /* 取出该类设备在设备表中的起始地址 */
j = equiptype[i].count; /* 取出该类设备的数量 */
k = 0;
z = t+j;
for(; t<z; t++)
if(strcmp(equipment[t].jobname,l)==0&&equipment[t].remain==1)
{
equipment[t].remain=0;
k++;
}
equiptype[i].remain = equiptype[i].remain+k;
if(k==0)
printf(" 工作台尚未使用这种设备类别! \n");
printf(" 回收成功! \n");
}
int main()
{
char l[4],type[10];
int i,mm,a;
//设备类表初始化
strcpy(equiptype[0].type,"input");//输入机
equiptype[0].count=2;
equiptype[0].remain=2;
equiptype[0].address=0;
strcpy(equiptype[1].type,"printer");//打印机
equiptype[1].count=3;
equiptype[1].remain=3;
equiptype[1].address=2;
strcpy(equiptype[2].type,"disk");//磁盘机
equiptype[2].count=4;
equiptype[2].remain=4;
equiptype[2].address=5;
strcpy(equiptype[3].type,"tape");//磁带机*/
equiptype[3].count=1;
equiptype[3].remain=1;
equiptype[3].address=9;
//设备表初始化
for(i=0; i<10; i++) /*每个设备设一个唯一的名字,初始化时每个设备都是好的,并且没有分配出去*/
{
equipment[i].number = i;
equipment[i].status = 1;
equipment[i].remain = 0;
}
cout<<"******************************"<<endl;
cout<<"**独占设备分配与回收模拟系统**"<<endl;
cout<<"************22王旭************"<<endl;
cout<<"******************************"<<endl;
while(1) //输入界面进行设备的分配和回收
{
printf("\n0-退出,1-分配,2-回收,3-显示,4-用户登录");
printf("\n选择功能项(0-4):");
scanf("%d",&a);
switch(a)
{
case 0://a=0程序结束
printf("感谢使用本程序 ^_^");
return 0;
case 1://a=1分配设备
printf("输入作业名、作业所需设备类和设备相对号");
scanf("%s%s%d",l,type,&mm);
allocate(l,type,mm);
break;
case 2://a=2回收设备
printf("输入作业名和作业归还的设备类");
scanf("%s %s",l,type);
reclaim(l,type);
break;
case 3://a=3输出设备类表和设备表的内容
printf("\n输出设备类表\n");
printf(" 设备类型 设备总量 空闲好设备\n");
for(i=0; i<n; i++)
printf("%9s%6d%9d\n",equiptype[i].type,equiptype[i].count,equiptype[i].remain);
printf("输出设备表:\n");
printf("绝对号 好/坏 已/未分配 占用作业名 相对号\n");
for(i=0; i<m; i++)
printf("%3d%8d%9d%12s%8d\n",equipment[i].number,
equipment[i].status,equipment[i].remain,equipment[i].jobname,
equipment[i].lnumber);
break;
case 4:{
cout << "请输入用户名:" << endl;
string username, password;
cout<<"username:";
cin>>username; // 用户名
cout<<"password:";
cin>>password;
// 这里可以添加用户验证逻辑
if (username == expected_username && password == expected_password) {
cout << "用户名:" << username << " 登录成功!" << endl;
} else {
cout << "用户名或密码错误。" << endl;
}
break;
}
default:
cout<<"输入的选择错误请重新选择"<<endl;
}
}
}
-
程序运行结果截图
运行程序
首先显示的是功能选项
首先输入3回车,显示设备原始信息
输入3会打印输出设备类表和输出设备表的状态。如下图的初始状态。
接下来依次测试各个函数
(设备分配函数,设备回收函数,设备显示函数,以及退出)
1.输入1回车,然后再输入“aa cpu 1”回车,观察运行结果。
在备类表初始化没有cpu这个类型,所以会分配失败。
2.输入1回车,然后再输入“aa input 99”回车,连续进行三次,然后显示设备信息,观察运行结果。在输入的第一次进行设备分配之后,设备类型的现存可用设备台数会-1,即2-1=1.在输入的第二次进行设备分配之后,设备类型的现存可用设备台数也会减一,即1-1=0.但在输入的第三次进行设备分配之后,设备类型的现存可用设备台数也会减一,但现存设备数量为0,所有会分配失败。
3.输入2回车,然后再输入“aa input”回车,连续进行三次,进行设备回收,观察运行结果。
在输入的第一次进行设备回收之后,设备类型的现存可用设备台数会+1,即0+1=1.在输入的第二次进行设备回收之后,设备类型的现存可用设备台数也会+1,即1+1=2.但在输入的第三次进行设备回收之后,设备类型的现存可用设备台数也会+1,但现存设备数量为2,达到顶峰,所有会回收失败
打印输出设备表
退出程序
-
实验遇到问题及解决处理方法
- 程序在运行时没有崩溃,但是程序的函数无法正常调用,无法正常显示
处理方法:通过debug和分析代码发现,程序在传送参数时返回不正确,造成有时候函数不正确
2在运行过程中,程序可以正常运行,但是逻辑上有问题,比如,只有三个设备,但是使用可以分配四次,或者是回收四次
处理方法,发现是程序的逻辑有问题,在判定时多写了一个等号,造成程序和预想的运行结果有偏差
通过这次实验,我了解了设备管理的基本概念、基本原理、常用的数据结构、分配策略及算法,能够编制一个独占设备的分配和回收模拟程序对已学的知识加以运用。
实验心得感悟
实验不仅加深了我对设备管理理论知识的理解,而且通过编程实践,我学会了如何将理论知识应用到具体的算法和数据结构设计中。
在实验过程中,我首先对设备管理的基本概念和原理进行了复习,包括独占设备的静态分配方式、设备分配表的构成等。通过设计和实现设备分配与回收的模拟程序,我对这些概念有了更加深入的认识。
编程实现阶段,我遇到了一些挑战。例如,在设备分配和回收的逻辑处理上,我最初没有正确地处理设备状态的更新,导致程序出现了一些逻辑错误。通过不断的调试和修正,我学会了如何仔细检查代码,确保每一步操作都符合预期。这个过程锻炼了我的编程能力和问题解决能力。
在实验的最后阶段,我通过多次测试和验证,确保了程序的正确性和健壮性。我意识到,一个成功的程序不仅需要正确的逻辑,还需要良好的用户交互设计。因此,我在程序中添加了用户登录功能,并优化了用户界面,以提供更友好的用户体验。
总的来说,这次实验不仅让我对操作系统的设备管理有了更深入的理解,而且提升了我的编程实践能力。