实验目的:
模拟实现包括设备的添加和删除,设备的分配和回收,体现设备分配中的设备独立性。
内容要求:
1、 设备管理模拟计算机系统的外围设备的系统结构,可以创建2个通道、3个控制器和四个外设(键盘、鼠标、显示器、打印机),键盘和鼠标使用一个控制器。
2、 设备管理有添加和删除设备的功能,同时完成控制器的维护功能。
3、 设备管理还包括设备的分配和回收。使学生掌握外围设备的体系结构和管理方法。成功分配的时候,用户进程使用设备,否则将被阻塞到一个级别的控制表上,等待被唤醒。
设备分配必须满足设备的独立性要求。为了实现设备独立性,要求在驱动程序之上设计一层设备无关软件,其主要功能可分为执行所有设备的公有操作,主要包括:(a)独占设备的分配与回收;(b)将逻辑设备名映射为物理设备,进一步可以找到相应物理设备的驱动程序。
实现功能:
1、增加设备
2、删除设备
3、申请设备
4、回收设备
5、显示当前所有设备的状态
实现过程:
#include<iostream> #include<string.h> #include<windows.h> 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<<COCT[i].name<<"\t"; char name[100]; cout<<endl<<"输入所选控制器的名称:"; cin>>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<<COCT[i].name<<"\t"; cout<<endl<<"请输入新建控制器的名称:"; cin>>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<<CHCT[i].name<<"\t"; cout<<endl<<"请输入所选通道的名称:"; cin>>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┏━━━━━━━━━━━━━━━━━━┓"<<endl; cout<<"\t\t┃ A、增加设备 ┃"<<endl; cout<<"\t\t┃ D、删除设备 ┃"<<endl; cout<<"\t\t┃ S、申请设备 ┃"<<endl; cout<<"\t\t┃ R、回收设备 ┃"<<endl; cout<<"\t\t┃ H、显示当前所有设备的状态 ┃"<<endl; cout<<"\t\t┃ E、退出 ┃"<<endl; cout<<"\t\t┗━━━━━━━━━━━━━━━━━━┛"<<endl; } void showSDT() { int i; for(i = 0 ; i < SDT_N ; i ++) cout<<SDT[i].name<<"\t"; cout<<endl; } void showAll() { int i; cout<<"\t\t\t系统设备表(SDT)"<<endl; cout<<"\t\t\t━━━━━━━━"<<endl; cout<<"\t名称\t\t"; for(i = 0 ; i < SDT_N ; i ++) { cout<<SDT[i].name<<"\t";} cout<<endl<<"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"<<endl; cout<<"\t\t\t设备控制表(DCT)"<<endl; cout<<"\t\t\t━━━━━━━━"<<endl; cout<<"\t名称\t\t"; for(i = 0 ; i < SDT_N ; i ++) cout<<SDT[i].DCT.name<<"\t"; cout<<endl; cout<<"\t类型\t\t"; for(i = 0 ; i < SDT_N ; i ++) cout<<SDT[i].DCT.type<<"\t"; cout<<endl; cout<<"\t状态\t\t"; for(i = 0 ; i < SDT_N ; i ++) cout<<SDT[i].DCT.stage<<"\t"; cout<<endl; cout<<"\t对应coct\t"; for(i = 0 ; i < SDT_N ; i ++) cout<<COCT[SDT[i].DCT.coct].name<<"\t"; cout<<endl; cout<<"\t阻塞队列\n"; for(i = 0 ; i < SDT_N ; i ++) { BLOCK *p; p=SDT[i].DCT.BLOCK; cout<<"\t"<<SDT[i].name<<"->"; while(p) { cout<<p->name<<"(from :"<<p->from<<")"<<"\t"; p=p->next; } cout<<endl; } cout<<endl<<"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"<<endl; cout<<"\t\t\t控制器控制表(COCT)"<<endl; cout<<"\t\t\t━━━━━━━━"<<endl; cout<<"\t名称\t\t"; for(i=0;i<COCT_N;i++) cout<<COCT[i].name<<"\t"; cout<<endl; cout<<"\t状态\t\t"; for(i=0;i<COCT_N;i++) cout<<" "<<COCT[i].stage<<"\t"; cout<<endl; cout<<"\t对应CHCT\t "; for(i=0;i<COCT_N;i++) cout<<CHCT[COCT[i].chct].name<<"\t "; cout<<endl; cout<<"\t阻塞队列\n"; for(i=0;i<COCT_N;i++) { BLOCK *p; p=COCT[i].BLOCK; cout<<"\t"<<COCT[i].name<<"->"; while(p) { cout<<p->name<<"(from :"<<p->from<<")"<<"\t"; p=p->next; } cout<<endl; } cout<<endl<<"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"<<endl; cout<<"\t\t\t通道控制表(CHCT)"<<endl; cout<<"\t\t\t━━━━━━━━"<<endl; cout<<"\t名称\t\t"; for(i=0;i<2;i++) cout<<CHCT[i].name<<"\t"; cout<<endl; cout<<"\t状态\t\t"; for(i=0;i<2;i++) cout<<" "<<CHCT[i].stage<<"\t"; cout<<endl; cout<<"\t阻塞队列\n"; for(i=0;i<2;i++) { BLOCK *p; p=CHCT[i].BLOCK; cout<<"\t"<<CHCT[i].name<<"->"; if(p!=NULL) p=p->next; while(p) { cout<<p->name<<"(from :"<<p->from<<")"<<"\t"; p=p->next; } cout<<endl; } cout<<"\t分配设备成功的进程名称:"<<endl;; for(i=0;i<2;i++) { cout<<"\t"<<CHCT[i].name<<"->"; if(CHCT[i].BLOCK != NULL) cout<<CHCT[i].BLOCK->name<<"(from "<<CHCT[i].BLOCK->from<<")"<<endl; cout<<endl; } cout<<endl; cout<<endl<<"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"<<endl; } bool judgeProcess(char *name) { BLOCK *b; int i,j,k,l; for(i = 0 ; i < SDT_N ; i ++) { b = SDT[i].DCT.BLOCK; while(b) { if(strcmp(b->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<<" 成功。"<<endl; } else { while(!judgeSDT(equipment)) { cout<<"当前设备有:"; showSDT(); cout<<"有重名设备。\n请重新输入设备名称:"; cin>>equipment; } add(equipment,type); cout<<"创建设备 "<<equipment<<" 成功。"<<endl; } } else if(order == 'D' || order == 'd') /*删除设备*/ { cout<<"输入需要删除的设备的名称:"; cin>>equipment; if(judgeSDT(equipment)) { while(!judgeSDT(equipment)) { cout<<"当前设备有:"; showSDT(); cout<<"没有"<<equipment<<"设备。\n请重新输入:"; cin>>equipment; } del(equipment); cout<<"删除设备 "<<equipment<<" 成功。"<<endl; } else { del(equipment); cout<<"删除设备 "<<equipment<<" 成功。"<<endl; } } else if(order == 'S' || order == 's') /*申请设备*/ { int success; cout<<"输入进程名:"; cin>>process; if(judgeProcess(process)) { cout<<"输入需要申请哪个设备:"; cin>>equipment; if(!judgeSDT(equipment)) { while(judgeSDT(equipment)) { cout<<"当前设备有:"; showSDT(); cout<<"没有"<<equipment<<"设备。\n请重新输入:"; cin>>equipment; } } } else { while(!judgeProcess(process)) { cout<<"已有重名进程。\n请重新输入进程名:"; cin>>process; } cout<<"输入需要申请哪个设备:"; cin>>equipment; if(judgeSDT(equipment)) { while(!judgeSDT(equipment)) { cout<<"当前设备有:"; showSDT(); cout<<"没有"<<equipment<<"设备。\n请重新输入:"; cin>>equipment; } } } success=apply(process,equipment); if(success == 1) cout<<process<<" 申请设备 "<<equipment<<" 成功。"<<endl; if(success == 2) cout<<process<<" 被阻塞到了CHCT上。"<<endl; if(success == 3) cout<<process<<" 被阻塞到了COCT上。"<<endl; if(success == 4) cout<<process<<" 被阻塞到了DCT上。"<<endl; } else if(order == 'R' || order == 'r') /*回收设备*/ { cout<<"输入需要回收设备的进程名称:"; cin>>process; cout<<"输入需要回收的设备名称:"; cin>>equipment; if(judgeSDT(equipment)) { while(!judgeSDT(equipment)) { cout<<"当前设备有:"; showSDT(); cout<<"没有"<<equipment<<"设备。\n请重新输入:"; cin>>equipment; } recycle(process,equipment); cout<<process<<" 回收设备 "<<equipment<<" 成功。"<<endl; } else { recycle(process,equipment); cout<<process<<" 回收设备 "<<equipment<<" 成功。"<<endl; } } else if(order == 'H' || order == 'h') { showAll(); } else if(order == 'E' || order == 'e') { exit(0); } else { cout<<"错误命令!\n"; } } int main() { init(); showAll(); getchar(); system("cls"); while(1) { menu(); cometrue(); showAll(); getchar();getchar(); system("cls"); } return 0; }