作業系統 實驗三 裝置管理
阿新 • • 發佈:2019-01-28
實驗目的:
模擬實現包括裝置的新增和刪除,裝置的分配和回收,體現裝置分配中的裝置獨立性。
內容要求:
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; }