为了提高操作系统的可适应性和可扩展性,现代操作系统中都毫无例外地实现了设备独立性,又叫做设备无关性。设备独立性的含义是:应用程序独立于具体使用的物理设备。
为了实现独占设备的分配,系统设置数据表格的方式也不相同,在实验中只要设计合理即可。这里仅仅是一种方案,采用设备类表和设备表。
(1) 数据结构
操作系统设置“设备分配表”,用来记录计算机系统所配置的独占设备类型、台数以及分配情况。设备分配表可由“设备类表”和“设备表”两部分组成。
(2) 设备分配
1) 当进程申请某类设备时,系统先查“设备类表”。
2) 如果该类设备的现存台数可以满足申请要求,则从该类设备的“设备表”始址开始依次查该类设备在设备表中的登记项,找出“未分配”的设备分配给进程。
3) 分配后要修改设备类表中的现存台数,把分配给进程的设备标志改为“已分配”且填上占用设备的进程名。
4) 然后,把设备的绝对号与相对号的对应关系通知用户,以便用户在分配到的设备上装上存储介质。
(3) 设备回收
当进程执行结束撤离时应归还所占设备,系统根据进程名查设备表,找出进程占用设备的登记栏,把标志修改为“未分配”,清除进程名。同时把回收的设备台数加到设备类表中的现存台数中。
#include "iostream"
#include "string"
#include "vector"
using namespace std;
typedef struct node
{
string ID; //进程名
string equipment; //申请的设备名
struct node *next;
}PCB;
typedef struct
{
string channelID; //通道标识符
bool state; //通道状态
PCB *use; //正在使用该通道的进程
PCB *blockqueue; //阻塞队首
}CHCT;
typedef struct
{
string controllerID; //控制器标示
bool state; //控制器状态
CHCT *front; //通道表指针
PCB *use; //正在使用该控制器的进程
PCB *blockqueue; //阻塞队首
}COCT;
typedef struct
{
char type; //设备类型
string equipmentID; //设备名
bool state; //设备状态
COCT *front; //控制器指针
PCB *use; //正在使用该设备的进程
PCB *blockqueue; //阻塞队首
}DCT;
typedef struct
{
char type; //设备类型
string equipmentID; //设备名
DCT *dct; //设备的DCT
}SDT;
DCT *k=new DCT; //键盘的DCT
DCT *m=new DCT; //mouse
DCT *p=new DCT; //printer
DCT *t=new DCT; // 显示
COCT *c1=new COCT; //control
COCT *c2=new COCT;
COCT *c3=new COCT;
CHCT *h1=new CHCT; //channel
CHCT *h2=new CHCT;
CHCT *h3=new CHCT;
int check(char cmd)
{
switch(cmd)
{
case 'c': //申请
return 1;
case 'C':
return 1;
case 'd': //删除
return 2;
case 'D':
return 2;
case 'a': //添加
return 3;
case 'A':
return 3;
case 'f': //释放 free
return 4;
case 'F':
return 4;
case 'q':
return -1;
case 'Q':
return -1;
case 'p':
return 5;
case 'P':
return 5;
default:
return 0;
}
}
void init(vector &SDT_table)
{
SDT_table[0].equipmentID="M";
SDT_table[0].type='2'; //鼠标是第二类设备
SDT_table[0].dct=m; //设备的DCT表位置
SDT_table[1].equipmentID="K";
SDT_table[1].type='1';
SDT_table[1].dct=k;
SDT_table[2].equipmentID="P";
SDT_table[2].type='3';
SDT_table[2].dct=p;
SDT_table[3].equipmentID="T";
SDT_table[3].type='4';
SDT_table[3].dct=t;
h1->blockqueue=NULL;
h1->channelID="通道1";
h1->state=true;
h1->use=NULL;
h2->blockqueue=NULL;
h2->channelID="通道2";
h2->state=true;
h2->use=NULL;
c1->blockqueue=NULL;
c1->controllerID="控制器1";
c1->state=true;
c1->front=h1;
c1->use=NULL;
c2->blockqueue=NULL;
c2->controllerID="控制器2";
c2->state=true;
c2->front=h1;
c2->use=NULL;
c3->blockqueue=NULL;
c3->controllerID="控制器3";
c3->state=true;
c3->front=h2;
c3->use=NULL;
k->blockqueue=NULL;
k->equipmentID="K";
k->state=true; //可用
k->type='1';
k->front=c1;
k->use=NULL;
m->blockqueue=NULL;
m->equipmentID="M";
m->state=true;
m->type='2';
m->front=c1;
m->use=NULL;
p->blockqueue=NULL;
p->equipmentID="P";
p->state=true;
p->type='3';
p->front=c2;
p->use=NULL;
t->blockqueue=NULL;
t->equipmentID="T";
t->state=true;
t->type='4';
t->front=c3;
t->use=NULL;
}
int main()
{
char cmd;
DCT *temp_dct;
COCT *temp_coct;
CHCT *temp_chct;
int l=0;
string ID;
string name;
vector SDT_table(4); //设备表
vector DCT_table(4); //设备
vector COCT_table(3); //控制器表
// vector::size_type size_SDT_table; //设备表长度
init(SDT_table); //设备表的初始化
DCT u=*k;
DCT_table.push_back(u);
u=*m;
DCT_table.push_back(u);
u=*p;
DCT_table.push_back(u);
u=*t;
DCT_table.push_back(u);
COCT cu=*c1;
COCT_table.push_back(cu);
cu=*c2;
COCT_table.push_back(cu);
cu=*c3;
COCT_table.push_back(cu);
cout<<"目前设备:K:键盘(1) M:鼠标(2) P:打印机(3) T:显示器(4)"<cout<<"操作指令C 申请使用设备。"<cout<<"操作指令D 删除设备。"<cout<<"操作指令A 添加设备。"<cout<<"操作指令F 释放设备。"<while(l!=-1)
{
cout<<">";
cin>>cmd;
l=check(cmd);
if(l==0)
{
cout<<"指令错误请重新输入。"<continue;
}
else if(l==1) //申请使用设备
{
cout<<"想要使用的设备名:"<cin>>ID;
cout<<"申请设备的进程名:"<cin>>name;
PCB *head=new PCB; //申请PCB的创建和链接
head->equipment=name;
head->ID=ID;
head->next=NULL;
bool find=false;
vector ::iterator ator0;
for(ator0=SDT_table.begin();ator0!=SDT_table.end();ator0++)
{
if(ator0->equipmentID==ID)
{
find=true; //有该设备
break;
}
}
if(!find)
{
cout<<"没有该设备,请重新输入操作指令。"<continue;
}
temp_dct=ator0->dct;
if(!temp_dct->state) //设备忙
{
cout<<"该设备目前处于忙状态,已经把请求加入等待队列。"<if(!temp_dct->blockqueue) //阻塞的队列为空
{
temp_dct->blockqueue=head;
}
else //阻塞队列已经有内容
{
PCB* t=temp_dct->blockqueue;
while(t)
t=t->next;
if(!t)
{
temp_dct->blockqueue=NULL;
}
else
t->next=head;
}
}
else //设备空闲
{
temp_coct=temp_dct->front;
temp_dct->state=false;
temp_dct->use=head; //添加正在占用设备的进程
if(!temp_coct->state) //控制器不可用
{
cout<<"目前该设备连接的控制器忙,已经把请求加入等待队列."<if(!temp_coct->blockqueue) //阻塞的队列为空
{
temp_coct->blockqueue=head;
}
else //阻塞队列不空
{
PCB* t=temp_coct->blockqueue;
while(t)
t=t->next;
if(!t)
{
temp_dct->blockqueue=NULL;
}
else
t->next=head;
}
}
else //控制器可用
{
temp_coct->state=false; //控制器置忙
temp_chct=temp_coct->front;
temp_coct->use=head;
if(!temp_chct->state) //通道不可用
{
cout<<"目前该设备连接的通道忙,已经把请求加入等待队列."<if(!temp_chct->blockqueue) //阻塞队列为空
{
temp_chct->blockqueue=head;
}
else //阻塞队列不为空
{
PCB* t=temp_coct->blockqueue;
while(t)
t=t->next;
if(!t)
{
temp_dct->blockqueue=NULL;
}
else
t->next=head;
}
}
else //通道可用
{
temp_chct->use=head;
temp_chct->state=false; //通道状态置忙
cout<<"该设备已经成功申请,请输入下一条指令."<else if(l==2) //删除设备
{
vector ::iterator ator;
vector ::iterator ator1;
cout<<"现在系统拥有的设备如下:"<for(ator=SDT_table.begin();ator!=SDT_table.end();ator++)
{
cout<equipmentID<<" ";
}
cout<<"请输入想要删除的设备名:";
cin>>name;
for(ator=SDT_table.begin();ator!=SDT_table.end();ator++)
{
if(ator->equipmentID==name) //查找到了该设备
{
ator1=ator->dct;
COCT *temp=ator1->front;
ator->dct=NULL;
SDT_table.erase(ator); //从设备表中删除
ator=SDT_table.begin();
/*
for(ator=SDT_table.begin();ator!=SDT_table.end();ator++)
cout<equipmentID<<" ";
cout<
if(temp->use)
{
if(temp->use->equipment==name) //该设备正在占用控制器
{
if(!temp->blockqueue) //控制器的等待队列为空
{
temp->state=true;
temp->use=NULL;
}
else //控制器的等待队列有内容
{
PCB *tt=temp->blockqueue;
temp->blockqueue->next=tt->next;
temp->use=tt;
tt->next=NULL;
}
}
else //该设备没有占用控制器
{
temp->blockqueue=NULL;
}
}
ator1->blockqueue=NULL;
ator1->front=NULL;
ator1->use=NULL;
vector ::iterator ator2;
vector D;
for(ator2=DCT_table.begin();ator2!=DCT_table.end();ator2++)
{
if(ator2!=ator1)
D.push_back(*ator2);
}
DCT_table=D;
// ator1=DCT_table.erase(ator1); //删除该设备
break;
}
}
if(ator==SDT_table.end()) //判断是否查找到设备
{
cout<<"没有该设备,请重新输入操作指令"<else
{
cout<<"成功删除该设备,请输入下一条操作指令。"<else if(l==3) //添加设备
{
SDT SDT_add;
DCT DCT_add;
int select;
cout<<"输入要添加的设备名称:";
cin>>DCT_add.equipmentID;
SDT_add.equipmentID=DCT_add.equipmentID;
cout<<"输入设备的类型(单个数字或单个字母):";
cin>>DCT_add.type;
SDT_add.type=DCT_add.type;
SDT_add.dct=&DCT_add;
DCT_add.blockqueue=NULL;
DCT_add.use=NULL;
DCT_add.state=true;
SDT_table.push_back(SDT_add);
DCT_table.push_back(DCT_add);
cout<<"是否需要新增控制器: 1.新增 2.使用已存在的"<cin>>select;
if(select==1) //新增
{
COCT c;
c.blockqueue=NULL;
c.state=true;
cout<<"输入控制器的名称(如:控制器1):";
cin>>c.controllerID;
c.use=NULL;
DCT_add.front=&c;
cout<<"1."<channelID<<'\t'<<"2."<channelID<cout<<"链接到哪个通道:";
cin>>select;
if(select==1) //链接到两个不同的通道
{
c.front=h1;
}
else
{
c.front=h2;
}
cout<<"连接成功."<else //利用以前的控制器
{
for(vector ::iterator ator=COCT_table.begin();ator!=COCT_table.end();ator++) //输出现有控制器名称
{
cout<controllerID<cout<<"选择的控制器名是(如:控制器1):";
cin>>name;
for(ator=COCT_table.begin();ator!=COCT_table.end();ator++) //按名字进行选择
{
if(ator->controllerID==name)
{
DCT_add.front=ator;
cout<<"链接成功,请输入下一条指令."<break;
}
}
}
}
else if(l==4) //释放设备资源
{
cout<<"想要释放的设备名:";
cin>>name;
DCT *DCT_temp; //暂存DCT
COCT *COCT_temp; //暂存COCT
CHCT *CHCT_temp; //暂存CHCT
for(vector ::size_type i=0;iif(SDT_table[i].equipmentID==name)
{
DCT_temp=SDT_table[i].dct;
COCT_temp=DCT_temp->front;
CHCT_temp=COCT_temp->front;
if(!DCT_temp->use) //如果该设备没有被使用
{
cout<<"该设备未被占用,无需释放。"<break;
}
else //设备现在被占用
{
if(CHCT_temp->use->ID==name) //该设备目前占用通道时
{
if(!CHCT_temp->blockqueue) //通道的等待队列无内容
{
CHCT_temp->state=true;
CHCT_temp->use=NULL;
}
else //通道的等待队列不为空
{
CHCT_temp->use=CHCT_temp->blockqueue;
CHCT_temp->blockqueue=CHCT_temp->blockqueue->next;
}
}
if(COCT_temp->use->ID==name) //设备占用控制器
{
if(!COCT_temp->blockqueue) //控制器的等待队列为空
{
COCT_temp->use=NULL;
COCT_temp->state=true;
}
else //控制器等待队列有内容
{
COCT_temp->use=COCT_temp->blockqueue;
COCT_temp->blockqueue=COCT_temp->blockqueue->next;
}
}
if(!DCT_temp->blockqueue) //设备自身的等待队列
{ //为空
DCT_temp->state=true;
DCT_temp->use=NULL;
break;
}
else //该设备目前被其他进程申请(队列不空)
{
DCT_temp->use=DCT_temp->blockqueue;
DCT_temp->blockqueue=DCT_temp->blockqueue->next;
break;
}
if(!COCT_temp->use)
{
COCT_temp->use=DCT_temp->use;
COCT_temp->state=false;
if(!CHCT_temp->use)
{
CHCT_temp->use=COCT_temp->use;
CHCT_temp->state=false;
}
}
}
}
}
if(i==SDT_table.size())
{
cout<<"该设备不存在,请重新输入下一条操作指令。"<else
{
cout<<"成功释放该设备,请输入下一条指令。"<return 0;
}