实验目的:
模拟实现包括设备的添加和删除,设备的分配和回收,体现设备分配中的设备独立性。
内容要求:
1、 设备管理模拟计算机系统的外围设备的系统结构,可以创建2个通道、3个控制器和四个外设(键盘、鼠标、显示器、打印机),键盘和鼠标使用一个控制器。
2、 设备管理有添加和删除设备的功能,同时完成控制器的维护功能。
3、 设备管理还包括设备的分配和回收。使学生掌握外围设备的体系结构和管理方法。成功分配的时候,用户进程使用设备,否则将被阻塞到一个级别的控制表上,等待被唤醒。
设备分配必须满足设备的独立性要求。为了实现设备独立性,要求在驱动程序之上设计一层设备无关软件,其主要功能可分为执行所有设备的公有操作,主要包括:(a)独占设备的分配与回收;(b)将逻辑设备名映射为物理设备,进一步可以找到相应物理设备的驱动程序。实现功能:
1、增加设备
2、删除设备
3、申请设备
4、回收设备
5、显示当前所有设备的状态
实现过程:
#include
#include
#include
using namespace std;
struct BLOCK /*阻塞*/
{
char name[100]; /*阻塞态进程名称*/
char from[100];
BLOCK *next;
};
struct DCT /*设备控制表*/
{
char name[100]; /*设备名称*/
char type; /*设备类型:I/O*/
int stage; /*设备状态:1/0*/
int coct; /*连接相应控制器的控制器号*/
BLOCK *BLOCK,*rear; /*阻塞队列指针*/ /*阻塞队列尾指针*/
};
struct SDT /*系统设备表*/
{
char name[100]; /*系统设备名称*/
DCT DCT; /*绑定的相应设备*/
}SDT[100];
struct COCT /*控制器控制表*/
{
char name[100]; /*控制器名称*/
int stage; /*控制器状态:1/0*/
int chct; /*连接相应通道的通道号*/
BLOCK *BLOCK,*rear; /*阻塞队列*/ /*阻塞队列尾指针*/
}COCT[100];
struct CHCT /*通道控制表*/
{
char name[100]; /*通道名称*/
int stage; /*通道的状态:1/0*/
BLOCK *BLOCK,*rear; /*阻塞队列*/ /*阻塞队列尾指针*/
}CHCT[2];
int SDT_N=4;
int COCT_N=3;
void init() /*初始化*/
{
/*
初始化SDT和DCT 系统原有4个设备:K M T P
*/
strcpy(SDT[0].name,"K");
strcpy(SDT[0].DCT.name,SDT[0].name);
SDT[0].DCT.type = 'I';
SDT[0].DCT.stage = 0;
SDT[0].DCT.coct = 0;
SDT[0].DCT.BLOCK = SDT[0].DCT.rear = NULL;
strcpy(SDT[1].name,"M");
strcpy(SDT[1].DCT.name,SDT[1].name);
SDT[1].DCT.type = 'O';
SDT[1].DCT.stage = 0;
SDT[1].DCT.coct = 0;
SDT[1].DCT.BLOCK = SDT[1].DCT.rear = NULL;
strcpy(SDT[2].name,"T");
strcpy(SDT[2].DCT.name,SDT[2].name);
SDT[2].DCT.type = 'I';
SDT[2].DCT.stage = 0;
SDT[2].DCT.coct = 1;
SDT[2].DCT.BLOCK = SDT[2].DCT.rear = NULL;
strcpy(SDT[3].name,"P");
strcpy(SDT[3].DCT.name,SDT[3].name);
SDT[3].DCT.type = 'O';
SDT[3].DCT.stage = 0;
SDT[3].DCT.coct = 2;
SDT[3].DCT.BLOCK = SDT[3].DCT.rear = NULL;
/*
初始化COCT 系统原有3个控制器:CO1 CO2 CO3
*/
strcpy(COCT[0].name,"CO1");
strcpy(COCT[1].name,"CO2");
strcpy(COCT[2].name,"CO3");
COCT[0].stage = 0;
COCT[1].stage = 0;
COCT[2].stage = 0;
COCT[0].chct = 0;
COCT[1].chct = 1;
COCT[2].chct = 1;
COCT[0].BLOCK = COCT[0].rear = NULL;
COCT[1].BLOCK = COCT[1].rear = NULL;
COCT[2].BLOCK = COCT[2].rear = NULL;
/*
初始化CHCT 系统原有2个通道:CH1 CH2
*/
strcpy(CHCT[0].name,"CH1");
strcpy(CHCT[1].name,"CH2");
CHCT[0].stage = 0;
CHCT[1].stage = 0;
CHCT[0].BLOCK = CHCT[0].rear = NULL;
CHCT[1].BLOCK = CHCT[1].rear = NULL;
}
/*设备维护*/
bool judgeSDT(char *name)
{
int i;
for(i = 0 ; i < SDT_N ; i ++)
{
if(strcmp(SDT[i].name,name) == 0) /*有重名设备,新建失败,返回0*/
return false;
}
if(i == SDT_N)
return true;
}
void add(char *name,char type) /*新建设备*/
{
int i;
strcpy(SDT[SDT_N].name,name);
strcpy(SDT[SDT_N].DCT.name,name);
SDT[SDT_N].DCT.stage = 0; /*状态置0*/
SDT[SDT_N].DCT.type = type;
int choose;
cout<<"1、选用已有控制器 2、新建控制器\n>";
cin>>choose;
if(choose == 1) /*选用已有控制器*/
{
cout<<"现有控制器为:";
for(i = 0 ; i < COCT_N ; i ++)
cout<>name;
for(i = 0 ; i < COCT_N ; i ++)
if(strcmp(COCT[i].name,name) == 0)
break;
SDT[SDT_N].DCT.coct = i;
}
if(choose==2) /*新建控制器*/
{
char name[100];
cout<<"现有控制器为:";
for(i = 0 ; i < COCT_N ; i ++)
cout<>name;
strcpy(COCT[COCT_N].name,name);
for(i = 0 ; i < COCT_N ; i ++)
{
if(strcmp(COCT[i].name,name) == 0)
break;
}
SDT[SDT_N].DCT.coct = i;
cout<<"现有通道为:";
for(i = 0 ; i < 2 ; i ++)
cout<>name;
for(i = 0 ; i < 2 ; i ++)
{
if(strcmp(CHCT[i].name,name) == 0)
break;
}
COCT[SDT[SDT_N].DCT.coct].chct = i;
COCT_N++;
}
SDT_N++;
}
void moveDCT(DCT *a,DCT *b)
{
strcpy(a->name,b->name);
a->BLOCK = b->BLOCK;
a->rear = b->rear;
a->coct = b->coct;
a->stage = b->stage;
a->type = b->type;
}
void del(char *name) /*删除设备name*/
{
int i,j,k;
for(i = 0 ; i < SDT_N ; i ++)
{
if(strcmp(SDT[i].name,name) == 0)
break;
}
BLOCK *p,*b;
p = b = COCT[SDT[i].DCT.coct].BLOCK;
while(b)
{
if(strcmp(b->from,name) == 0)
{
if(b == COCT[SDT[i].DCT.coct].BLOCK)
p = COCT[SDT[i].DCT.coct].BLOCK = b->next;
else
{
p->next = b->next;
delete b;
}
b = p;
}
p = b;
if(b != NULL)
b = b->next;
}
p = b = CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK;
while(b)
{
if(strcmp(b->from,name) == 0)
{
if(b == CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK)
p = CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = b->next;
else
{
p->next = b->next;
delete b;
}
b = p;
}
p = b;
if(b != NULL)
b = b->next;
}
if(CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK == NULL)
{
if(COCT[SDT[i].DCT.coct].BLOCK != NULL)
{
if(SDT[i].DCT.BLOCK == NULL)
SDT[i].DCT.stage = 0;
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = COCT[SDT[i].DCT.coct].BLOCK;
COCT[SDT[i].DCT.coct].BLOCK = COCT[SDT[i].DCT.coct].BLOCK->next;
}
else
{
if(SDT[i].DCT.BLOCK != NULL)
{
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = SDT[i].DCT.BLOCK;
SDT[i].DCT.BLOCK = SDT[i].DCT.BLOCK->next;
}
else
{
CHCT[COCT[SDT[i].DCT.coct].chct].stage = 0;
COCT[SDT[i].DCT.coct].stage = 0;
SDT[i].DCT.stage = 0;
for(j = 0 ; j < COCT_N ; j ++)
{
if(COCT[SDT[i].DCT.coct].chct == COCT[j].chct && j != i)
{
if(COCT[j].BLOCK != NULL)
{
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = COCT[j].BLOCK;
COCT[j].BLOCK = COCT[j].BLOCK->next;
CHCT[COCT[SDT[i].DCT.coct].chct].stage = 1;
break;
}
}
}
}
}
}
for(j = 0 ; j < SDT_N ; j ++)
{
if(SDT[i].DCT.coct == SDT[j].DCT.coct && j != i)
break;
}
if(j == SDT_N)
{
for(k = SDT[i].DCT.coct ; k < COCT_N-1 ; k ++)
{
strcpy(COCT[k].name,COCT[k+1].name);
COCT[k].stage = COCT[k+1].stage;
COCT[k].chct = COCT[k+1].chct;
COCT[k].BLOCK = COCT[k+1].BLOCK;
COCT[k].rear = COCT[k+1].rear;
}
for(k = 0 ; k < SDT_N ; k ++)
{
if(SDT[k].DCT.coct > SDT[i].DCT.coct)
SDT[k].DCT.coct--;
}
for(k = i ; k < SDT_N-1 ; k ++)
{
strcpy(SDT[k].name,SDT[k+1].name);
moveDCT(&SDT[k].DCT,&SDT[k+1].DCT);
}
SDT_N--;
COCT_N--;
}
else
{
for(k = i ; k < SDT_N-1 ; k ++)
{
strcpy(SDT[k].name,SDT[k+1].name);
moveDCT(&SDT[k].DCT,&SDT[k+1].DCT);
}
SDT_N--;
}
}
/*
设备分配
*/
int apply(char *p,char *name) /*申请设备, 进程p申请设备name*/
{
int i,j;
/*
从前往后查
*/
BLOCK *block;
block = new BLOCK;
strcpy(block->name,p);
strcpy(block->from,name);
block->next = NULL;
for(i = 0 ; i < SDT_N ; i ++)
{
if(strcmp(SDT[i].name,name) == 0)
break;
}
if(SDT[i].DCT.stage == 0) /*如果DCT的状态是0 则置1并继续往下查*/
{
SDT[i].DCT.stage = 1;
if(COCT[SDT[i].DCT.coct].stage == 0) /*如果COCT的状态是0 则置1并继续往下查*/
{
COCT[SDT[i].DCT.coct].stage = 1;
if(CHCT[COCT[SDT[i].DCT.coct].chct].stage == 0) /*如果CHCT的状态是0 则置1*/
{
CHCT[COCT[SDT[i].DCT.coct].chct].stage = 1;
if(CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK == NULL)
CHCT[COCT[SDT[i].DCT.coct].chct].rear = CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK= block;
/*代表进程p申请设备name过来的*/
return 1; /*申请成功*/
}
else /*如果CHCT的状态是1则需将该进程阻塞到CHCT的阻塞队列上*/
{
CHCT[COCT[SDT[i].DCT.coct].chct].rear->next = block;
CHCT[COCT[SDT[i].DCT.coct].chct].rear = block;
return 2; /*阻塞到了CHCT上*/
}
}
else /*如果COCT的状态是1,则需将该进程阻塞到COCT的阻塞队列上*/
{
if(COCT[SDT[i].DCT.coct].BLOCK == NULL)
COCT[SDT[i].DCT.coct].rear = COCT[SDT[i].DCT.coct].BLOCK = block;
else
{
COCT[SDT[i].DCT.coct].rear->next = block;
COCT[SDT[i].DCT.coct].rear = block;
}
return 3; /*阻塞到了COCT上*/
}
}
else /*如果DCT的状态是1,则需将该进程阻塞到DCT的阻塞队列上*/
{
if(SDT[i].DCT.BLOCK == NULL)
SDT[i].DCT.rear = SDT[i].DCT.BLOCK = block;
else
{
SDT[i].DCT.rear->next = block;
SDT[i].DCT.rear = block;;
}
return 4; /*阻塞到了DCT上*/
}
}
bool recycle(char *t,char *name) /*t回收设备name*/
{
/*
从后往前查
*/
int i,j,k;
for(i = 0 ; i < SDT_N ; i ++)
{
if(strcmp(SDT[i].name,name) == 0)
break;
}
BLOCK *b,*p,*q;
p = b = CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK;
while(b)
{
if(strcmp(b->name,t) == 0)
break;
p = b;
b = b->next;
}
if(b != NULL)
{
if(b == CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK)
{
q = CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK;
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = b->next;
delete q;
}
else
{
p->next = b->next;
delete b;
}
if(CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK == NULL)
{
if(COCT[SDT[i].DCT.coct].BLOCK != NULL)
{
if(SDT[i].DCT.BLOCK == NULL)
SDT[i].DCT.stage = 0;
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = COCT[SDT[i].DCT.coct].BLOCK;
COCT[SDT[i].DCT.coct].BLOCK = COCT[SDT[i].DCT.coct].BLOCK->next;
}
else
{
if(SDT[i].DCT.BLOCK != NULL)
{
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = SDT[i].DCT.BLOCK;
SDT[i].DCT.BLOCK = SDT[i].DCT.BLOCK->next;
}
else
{
CHCT[COCT[SDT[i].DCT.coct].chct].stage = 0;
COCT[SDT[i].DCT.coct].stage = 0;
SDT[i].DCT.stage = 0;
for(j = 0 ; j < COCT_N ; j ++)
{
if(COCT[SDT[i].DCT.coct].chct == COCT[j].chct && j != i)
{
if(COCT[j].BLOCK != NULL)
{
CHCT[COCT[SDT[i].DCT.coct].chct].BLOCK = COCT[j].BLOCK;
COCT[j].BLOCK = COCT[j].BLOCK->next;
CHCT[COCT[SDT[i].DCT.coct].chct].stage = 1;
break;
}
}
}
return true;
}
}
}
return true;
}
}
void menu()
{
cout<<"\t\t┏━━━━━━━━━━━━━━━━━━┓"<";
while(p)
{
cout<name<<"(from :"<from<<")"<<"\t";
p=p->next;
}
cout<";
while(p)
{
cout<name<<"(from :"<from<<")"<<"\t";
p=p->next;
}
cout<";
if(p!=NULL)
p=p->next;
while(p)
{
cout<name<<"(from :"<from<<")"<<"\t";
p=p->next;
}
cout<";
if(CHCT[i].BLOCK != NULL)
cout<name<<"(from "<from<<")"<name,name) == 0)
return false; /*有重名进程*/
b = b->next;
}
}
if(i == SDT_N)
{
for(j = 0 ; j < COCT_N ; j ++)
{
b = COCT[j].BLOCK;
while(b)
{
if(strcmp(b->name,name) == 0)
return false; /*有重名进程*/
b = b->next;
}
}
if(j == COCT_N)
{
for(k = 0 ; k < 2 ; k ++)
{
b = CHCT[k].BLOCK;
while(b)
{
if(strcmp(b->name,name) == 0)
return false; /*有重名进程*/
b = b->next;
}
}
if(k == 2)
{
return true; /*没有重名进程*/
}
}
}
}
void cometrue()
{
char order; char process[100]; char equipment[100]; char type;
cout<<"请输入命令:";
cin>>order;
if(order == 'A' || order == 'a') /*增加设备*/
{
cout<<"输入增加的设备名称"; cin>>equipment;
cout<<"输入设备类型(I/O):"; cin>>type;
if(judgeSDT(equipment))
{
add(equipment,type);
cout<<"创建设备 "<>equipment;
}
add(equipment,type);
cout<<"创建设备 "<>equipment;
if(judgeSDT(equipment))
{
while(!judgeSDT(equipment))
{
cout<<"当前设备有:";
showSDT();
cout<<"没有"<>equipment;
}
del(equipment);
cout<<"删除设备 "<>process;
if(judgeProcess(process))
{
cout<<"输入需要申请哪个设备:"; cin>>equipment;
if(!judgeSDT(equipment))
{
while(judgeSDT(equipment))
{
cout<<"当前设备有:";
showSDT();
cout<<"没有"<>equipment;
}
}
}
else
{
while(!judgeProcess(process))
{
cout<<"已有重名进程。\n请重新输入进程名:";
cin>>process;
}
cout<<"输入需要申请哪个设备:"; cin>>equipment;
if(judgeSDT(equipment))
{
while(!judgeSDT(equipment))
{
cout<<"当前设备有:";
showSDT();
cout<<"没有"<>equipment;
}
}
}
success=apply(process,equipment);
if(success == 1)
cout<>process;
cout<<"输入需要回收的设备名称:"; cin>>equipment;
if(judgeSDT(equipment))
{
while(!judgeSDT(equipment))
{
cout<<"当前设备有:";
showSDT();
cout<<"没有"<>equipment;
}
recycle(process,equipment);
cout<