设备管理
●基本要求:在前面的实验基础上实现设备管理功能的模拟,主要包括通道和控制器的添加和删除,设备的添加、删除,设备的分配和回收。
●实验提示:
1、假定模拟系统中已有键盘、鼠标、打印机和显示器四个设备,另有三个控制器和两个通道。
2、设备管理子系统涉及到系统设备表(SDT)、通道控制表(CHCT)、控制器控制表(COCT)和设备控制表(DCT)来体现输入输出系统的四级结构和三级控制。应实现上述数据结构来完成对外围设备的管理。
数据结构参考代码:
C/C++版:
struct Node{
char name[10]; //名称
struct PCB *process; //占用该节点的进程
struct PCB *waitinglist; //等待该节点的进程队列
struct Node *next; //下一个节点
struct Node *parent; //父节点
};
struct Node *CHCTs; //通道队列头节点
struct Node *COCTs; //控制器队列头节点
struct Node *DCTs; //设备队列头节点
Java版:
class IONode{
String name;
IONode next;
Process process;
Vector waitinglist;
IONode parent;
}
class CHCT extends IONode{}
class COCT extends IONode{}
class DCT extends IONode{}
3、实现上述设备、控制器以及通道的层次关系,同时能够添加或删除新的设备、控制器或通道。
4、通过键盘命令模拟进程执行过程中提出的设备分配或释放请求,并为此请求分配或释放设备。分配设备成功后可将进程状态调整为阻塞,释放设备后变为就绪状态。
5、分配设备时应如果该设备已被其它进程占用,则设备分配失败,请求进程进入阻塞状态,同时等待该设备的释放。如果设备空闲,进程占用设备的同时还应提出申请控制器请求,直到与设备相关的通道都已申请成功为止。
6、设备、控制器或通道的释放应引起对应节点的等待队列中的第一个阻塞进程被唤醒。如果被唤醒的进程还未完成申请操作,应继续执行上级节点的申请操作。
7、回收流程:
8、*体现设备独立性,可以在设备分配时只指定设备类型,如果有空闲设备即可分配。
●评分标准(满分15分):
要求必须完成以下几个方面的内容(10-12分):
●在第1、2部分基础上扩展;
●能够模拟设备的分配与回收流程;
●设备分配成功与否,进程都应进入阻塞状态;
●能够较形象地输出通道、控制器、设备的层次关系以及进程的占用、等待状态;
也可实现如下扩充要求(3-5分):
●能够添加、删除通道、控制器或设备;
●能够模拟SDT基础上的设备分配过程。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct PCB{
char name[10];
struct PCB *next;
}PCB,*PCBlist;
typedef struct Node{
char name[10];
PCBlist process;
PCBlist waitting;//占用的进程,等待队列
struct Node *next;
struct Node *parent;
}Node,*Nodelist;
PCBlist running,ready,blocked;
Nodelist DCTS,COCTS,CHCTS;
PCBlist remove_process(PCBlist head,PCBlist p)//将进程p从队列head中移除
{
PCBlist temp1=head;
PCBlist temp2=head->next;
while(temp1->next!=NULL)
{
if(temp2==p)
{
temp1->next=temp2->next;
temp2->next=NULL;//把temp2从队列中删除
return temp2;
}
temp1=temp2;
temp2=temp2->next;
}
return NULL;
}
void display_pcb(PCBlist head)//展示进程
{
PCBlist temp=head->next;
while(temp!=NULL)
{
printf("%s ",temp->name);
temp=temp->next;
}
}
void display_waitting(Nodelist head)//展示设备的等待队列
{
Nodelist temp=head->next;
while(temp!=NULL)
{
display_pcb(temp->waitting);
temp=temp->next;
}
}
void addpcb(PCBlist head,PCBlist node)//添加进程
{
if(node!=NULL)
{
PCBlist tmp=head;
//PCBlist L=head->next;
while(tmp->next!=NULL)
tmp=tmp->next;
tmp->next=node;
node->next=NULL;
}
}
PCBlist getFirstpcb(PCBlist head)//获取队列头
{
if(head->next!=NULL)
{
PCBlist tmp=head->next;
head->next=head->next->next;
tmp->next=NULL;
return tmp;
}
return NULL;
}
void create_process(char *name)//创建进程
{
PCBlist p=new PCB;
strcpy(p->name,name);
addpcb(ready,p);//将创建的进程添加到就绪队列中
if(running->next==NULL)//如果执行队列为空,则将就绪队列的队头变为执行队列
running->next=getFirstpcb(ready);
}
void createNewProcess()
{
char name[10];
int size;
printf("进程名称:");
scanf("%s",name);
create_process(name);
}
void timeout()//时间片到
{
if(running->next!=NULL)
{
addpcb(ready,running->next);
running->next=getFirstpcb(ready);
}
}
void blockCurrentProcess()//执行进程被阻塞
{
PCBlist tmp=getFirstpcb(running);
if(tmp!=NULL)
{
addpcb(blocked,tmp);
addpcb(running,getFirstpcb(ready));
}
else printf("当前执行进程为空!\n");
}
void wakeupBlockedProcess()//阻塞进程被唤醒
{
PCBlist tmp=getFirstpcb(blocked);
if(tmp!=NULL)
{
addpcb(ready,tmp);
if(running->next==NULL)
{
addpcb(running,getFirstpcb(ready));
}
}
else
printf("当前没有被阻塞的进程!\n");
}
void terminateRunningProcess()//执行进程被终止
{
int i,j;
PCBlist tmp=running->next;
if(tmp!=NULL)
{
running->next=NULL;
addpcb(running,getFirstpcb(ready));
}
else
printf("当前没有正在执行的进程!\n");
}
void display_process()//进程显示
{
//PCBlist tmp=ready->next;
printf("执行进程:");
display_pcb(running);
printf("\n就绪进程:");
display_pcb(ready);
printf("\n阻塞进程:");
display_pcb(blocked);
cout<<endl;
display_waitting(CHCTS);
display_waitting(COCTS);
display_waitting(DCTS);
printf("\n");
}
void block(PCBlist head,PCBlist p)//执行进程调用设备被阻塞 p为阻塞的进程,把p进程加入head队列
{
if(p->next!=NULL)
{
addpcb(head,p->next);
if(p==running)
running->next=getFirstpcb(ready);
}
else
printf("当前执行进程为空!\n");
}
int get_child_count( Nodelist node,Nodelist chile_head)//计算有多少个设备和node相连
{
int count=0;
Nodelist temp=chile_head->next;
while(temp!=NULL)
{
if(temp->parent==node)
count++;
temp=temp->next;
}
return count;
}
Nodelist FindByName(char *name, Nodelist node)//寻找设备在队列中的位置
{
Nodelist temp=node->next;
while(temp!=NULL)
{
if(strcmp(temp->name,name)==0)
return temp;
else
temp=temp->next;
}
printf("错误!未找到%s\n",name);
return NULL;
}
Nodelist Add_Node(char *name,Nodelist parent, Nodelist head)//添加设备 name添加设备的名字,parent为此设备的父节点,head为设备所在的队列
{
Nodelist temp=head;
while(temp->next!=NULL)
temp=temp->next;
temp->next=new Node;
strcpy(temp->next->name,name);
temp->next->next=NULL;
temp->next->parent=parent;
temp->next->process=NULL;
temp->next->waitting=new PCB ;
temp->next->waitting->next=NULL;
return temp->next;
}
void Delete_Node(char *name,Nodelist head)//删除设备,管理器,通道
{
Nodelist temp1=head;
Nodelist temp2=head->next;
while(temp2!=NULL)
{
if(strcmp(temp2->name,name)==0)//在队列中找到设备
{
if(temp2->process==NULL && temp2->waitting->next==NULL)//如果没有进程占用此设备则删除
{
temp1->next=temp2->next;
}
else
{
printf("错误!有进程正在占用,不可删除!%s\n",name);
}
return;
}
temp1=temp2;
temp2=temp2->next;
}
}
void Add_devices()//添加菜单
{
int i;
char name[10];
char parent[10];
while(1)
{
printf("1、添加设备\n");
printf("2、添加控制器\n");
printf("3、添加通道\n");
printf("0、返回\n");
scanf("%d",&i);
if(i!=0)
{
printf("name:");
scanf("%s",name);
}
if(i==1 || i==2)
{
printf("parent name:");
scanf("%s",parent);
}
switch(i)
{
case 1:
Add_Node(name,FindByName(parent,COCTS),DCTS);
break;
case 2:
Add_Node(name,FindByName(parent,CHCTS),COCTS);
break;
case 3:
Add_Node(name,NULL,CHCTS);
break;
case 0:
return;
}
}
}
void Delete_devices()//删除菜单
{
int i;
char name[10];
struct Node *temp;
while(1)
{
printf("1、删除设备\n");
printf("2、删除控制器\n");
printf("3、删除通道\n");
printf("0、返回\n");
scanf("%d",&i);
if(i!=0)
{
printf("name:");
scanf("%s",name);
}
switch(i)
{
case 1:
temp=FindByName(name,DCTS);
if(temp==NULL)
printf("错误!未找到%s\n",name);
else
Delete_Node(name,DCTS);
break;
case 2:
temp=FindByName(name,COCTS);
if(temp==NULL)
printf("错误!未找到%s\n",name);
else if(get_child_count(temp,DCTS)>0)//temp是控制器节点,此函数是查找temp的子节点DCTS设备节点的个数,如果有,则此处不可以删除该控制器节点
printf("错误!不可删除%s\n",name);
else
Delete_Node(name,COCTS);
break;
case 3:
temp=FindByName(name,CHCTS);
if(temp==NULL)
printf("错误!未找到%s\n",name);
else if(get_child_count(temp,COCTS)>0)//temp是控制器节点,此函数是查找temp的子节点DCTS设备节点的个数,如果有,则此处不可以删除该控制器节点
printf("错误!不可删除%s\n",name);
else
Delete_Node(name,CHCTS);
break;
case 0:
return;
}
}
}
void allocate_channel(Nodelist node, PCBlist p)//分配通道
{
if(p->next==NULL)
return;
if(node->process==NULL)
{
node->process=p->next;
block(blocked,p);//把执行进程添加到阻塞队列中
}
else
{
block(node->waitting,p);
}
}
void allocate_controller(Nodelist node, PCBlist p)//分配控制器
{
if(p->next==NULL)
return ;
if(node->process==NULL)
{
node->process=p->next;
allocate_channel(node->parent,p);//给控制器对应的通道分配进程
}
else
{
PCBlist l=p->next;
PCBlist t = node->waitting->next;
block(node->waitting,p);//若控制器有进程占用,则将进程添加到此控制器的阻塞队列中
}
}
void allocate_devices(Nodelist node, PCBlist p)//分配设备
{
if(p->next==NULL)
return ;
if(node->process==NULL)
{
node->process=p->next;
allocate_controller(node->parent,p);//给设备对应的控制器分配进程
}
else
{
block(node->waitting,p);//若设备被占用,则将进程添加到此设备的阻塞队列中
}
}
void Allocate()//分配
{
char name[10];
Nodelist node;
if(running->next==NULL)
return;
printf("device name:");
scanf("%s",name);
node=FindByName(name,DCTS);//在设备队列中找到要分配的设备
if(node==NULL)
return;
else
allocate_devices(node,running);
}
void release_channel(Nodelist node, PCBlist p)//释放通道
{
if(node->process==p)
{
node->process=NULL;
allocate_channel(node,node->waitting);//给等待队列中的第一个进程分配通道
getFirstpcb(node->waitting);
addpcb(ready,remove_process(blocked,p));//把释放的进程从阻塞队列中添加到就绪队列里
if(running->next==NULL)
running->next=getFirstpcb(ready);
}
else
{
addpcb(ready,remove_process(node->waitting,p));//把等待队列添加到就绪队列中
if(running->next==NULL)
running->next=getFirstpcb(ready);
}
}
void release_controller(Nodelist node, PCBlist p)//释放控制器
{
if(node->process==p)
{
node->process=NULL;
allocate_controller(node,node->waitting);
getFirstpcb(node->waitting);
release_channel(node->parent,p);//释放控制器所对应的通道
}
else
{
addpcb(ready,remove_process(node->waitting,p));
if(running->next==NULL)
running->next=getFirstpcb(ready);
}
}
void Release()//释放
{
char name[10];
struct Node *node;
struct PCB *temp;
printf("device name:");
scanf("%s",name);
node=FindByName(name,DCTS);
if(node==NULL || node->process==NULL)
return;
else
{
temp=node->process;
if(node->waitting->next==NULL)
{
node->process=NULL;
}
else
{
node->process=NULL;
allocate_devices(node,node->waitting);//设备
getFirstpcb(node->waitting);
release_controller(node->parent,temp);//释放设备对应的控制器
}
}
}
void display_process_status(Nodelist node)//显示节点的占用进程以及等待进程的信息
{
PCBlist p=node->waitting->next;
if(node->process!=NULL)//此处是显示占用进程
{
printf("<-%s",node->process->name);
}
while(p!=NULL)
{
printf("\t等待:");
printf("<--%s",p->name);
p=p->next;
}
printf("\n");
}
void Display_status()
{
Nodelist chct=CHCTS->next,coct=COCTS->next,dct=DCTS->next;
while(chct!=NULL)//显示通道
{
printf("%s",chct->name);
display_process_status(chct);
coct=COCTS->next;
while(coct!=NULL)//显示控制器
{
if(coct->parent==chct)
{
printf("\t%s",coct->name);
display_process_status(coct);
dct=DCTS->next;
while(dct!=NULL)//显示设备
{
if(dct->parent==coct)
{
printf("\t\t%s",dct->name);
display_process_status(dct);
}
dct=dct->next;
}
}
coct=coct->next;
}
chct=chct->next;
}
}
//初始化/菜单选项/主函数
void Init()
{
int i;
Nodelist chct,coct;
running=new PCB;
ready=new PCB;
blocked=new PCB;
ready->next=NULL;
running->next=NULL;
blocked->next=NULL;
create_process("a");
create_process("b");
create_process("c");
create_process("d");
create_process("e");
DCTS=new Node;
DCTS->next=NULL;
COCTS=new Node;
COCTS->next=NULL;
CHCTS=new Node;
CHCTS->next=NULL;
chct=Add_Node("CHCT1",NULL,CHCTS);
coct=Add_Node("COCT1",chct,COCTS);
Add_Node("K",coct,DCTS);
Add_Node("M",coct,DCTS);
chct=Add_Node("CHCT2",NULL,CHCTS);
coct=Add_Node("COCT2",chct,COCTS);
Add_Node("P",coct,DCTS);
chct=Add_Node("CHCT3",NULL,CHCTS);
coct=Add_Node("COCT3",chct,COCTS);
Add_Node("D",coct,DCTS);
}
void Menu(){
printf("----------进程管理----------\n");
printf("1:创建进程\n");
printf("2:时间片到\n");
printf("3:进程阻塞\n");
printf("4:进程唤醒\n");
printf("5:进程结束\n");
printf("6:显示进程状态\n");
printf("----------设备管理----------\n");
printf("7:添加\n");//设备或者通道或者控制器
printf("8:删除\n");
printf("9:分配设备\n");
printf("10:释放设备\n");
printf("11:查看设备状态\n");
printf("-1:退出\n");
}
int main()
{
int i;
Init();
while(1)
{
Menu();
scanf("%d",&i);
switch(i)
{
default:
printf("erro");
continue;
case 1:
createNewProcess();
break;
case 2:
timeout();
break;
case 3:
blockCurrentProcess();
break;
case 4:
wakeupBlockedProcess();
break;
case 5:
terminateRunningProcess();
break;
case 6:
display_process();
break;
case 7:
Add_devices();
break;
case 8:
Delete_devices();
break;
case 9:
Allocate();//分配
break;
case 10:
Release();//回收
break;
case 11:
Display_status();
break;
}
}
return 0;
}