外存空闲空间管理模块的设计与实现C语言Word文件下载.docx
《外存空闲空间管理模块的设计与实现C语言Word文件下载.docx》由会员分享,可在线阅读,更多相关《外存空闲空间管理模块的设计与实现C语言Word文件下载.docx(42页珍藏版)》请在冰点文库上搜索。
(1)空闲表法算法设计
空闲盘区的分配采用首次适应算法。
在系统为某新创建的文件分配空闲盘块时,先顺序地检索空闲表的各表项,直至找到第一个其大小能满足要求的空闲区,再将该盘区分配给用户,同时修改空闲表。
系统在对用户所释放的存储空间进行回收时,要考虑回收区是否与空闲表中插入点的前区和后区相邻接,对相邻接者予以合并。
(2)位示图法算法设计
盘块分配时,顺序扫描位示图,从中找出一个或一组其值为“0”的二进制位,转换成与之对应的盘块号,然后修改位示图。
盘块回收时,将回收盘块的盘块号转换成位示图的行号和列号,修改位示图。
5.流程图
5.1空闲表法流程图
(1)盘块分配流程图,如图5-1所示。
否
否是
是
否
(2)盘块回收流程图,如图5-2所示。
否否
是是
5-2空闲表法盘块回收流程图
5.2位示图法流程图
(1)盘块分配流程图,如图5-3所示。
是
图5-3位示图法盘块分配流程图
(2)盘块回收流程图,如图5-4所示。
是
图5-4位示图法盘块回收流程图
6.开发环境
Windows系统,运行环境:
VisualC++6.0。
7.结果分析
(1)运行首页面。
(2)输入1,选择位示图法。
(3)选择1,分配文件。
(4)输入文件名1和块数11。
(5)选择1,继续分配文件,并输入文件名2和块数22。
(6)输入1,继续分配文件,并输入文件名3和块数33。
(7)选择2,回收文件,并输入回收文件2。
(8)返回首页面,选择2,用空闲表法。
(9)输入256。
(10)输入1,选择分配,并且输入文件名1和大小11,查看分配状态。
(11)输入1,继续分配,并且输入文件名2和大小22,查看分配状态。
(12)输入2,选择回收,并且输入回收文件名2,查看分配状态。
8.课程设计总结
通过做这个实验,我明白了在做实验前,一定要将课本上的知识吃透,因为这是做实验的基础,否则,在老师讲解时就会听不懂,在编程序时就会思维混乱,摸不清头绪。
做实验时,一定要亲力亲为,务必要将每个步骤,每个细节弄清楚,弄明白。
实验后,还要复习,思考,这样印象才深刻,记得才牢固。
实验的过程中我们必须要弄懂实验的原理。
在这里我深深体会到哲学上理论对实践的指导作用:
弄懂实验原理,而且体会到了实验的操作能力是靠自己亲自动手,亲自开动脑筋,亲自去请教别人才能得到提高的。
在这里,感谢荆老师对我的指导和启迪,感谢同学们对我的帮助,这次实验虽然做的不算特别完美,不过我已经很努力了。
这次实验对我对这部分知识的理解和编程能力有了很大的提高,以后我会更加努力的去做每一件事。
参考文献
【1】汤晓丹、梁红兵·
计算机操作系统(第三版)西安:
西安电子科技大学出版社,2007年:
引用231页~233页。
【2】揣锦华·
C++程序设计语言(第一版)西安:
西安电子科技大学出版社,2003年。
【3】张坤、姜立秋·
操作系统实验教程(第一版)北京:
清华大学出版社,2008年。
附录:
#include<
stdio.h>
stdlib.h>
#include<
malloc.h>
windows.h>
string.h>
iostream.h>
intMAX_SEGMENT=10;
//最大碎片值
structPartition//分区表目
{
intPar_Size;
//分区大小
intPar_No;
//分区序号或者名字
intAddr;
//分区地址
intIsUse;
//分区使用情况,0表示空闲,1表示使用
Partition*pri;
//前向指针
Partition*next;
//后向指针
};
Partition*Int()//函数,返回Partition类型指针
{//初始化空闲分区表
Partition*list,*H,*H1;
list=(structPartition*)malloc(sizeof(structPartition));
list->
next=NULL;
H=list;
if(!
list)
{
printf("
\n错误,初始化分配失败!
程序结束"
);
exit
(1);
}
H1=(structPartition*)malloc(sizeof(structPartition));
printf("
请预先输入分区总大小(以盘块为单位):
"
scanf("
%d"
&
H1->
Par_Size);
H1->
Addr=0;
Par_No=0;
IsUse=0;
pri=H;
H->
next=H1;
////list--->
H1
returnlist;
}
Partition*InitFP()
{//初始化已分配分区表
Partition*FP,*F,*H;
inti;
FP=(structPartition*)malloc(sizeof(structPartition));
FP->
H=FP;
for(i=0;
i<
10;
i++)//已分配区先暂定分配十个表目
F=(structPartition*)malloc(sizeof(structPartition));
if(!
F)
{
printf("
\n错误,分配失败!
exit
(1);
}
F->
Par_Size=0;
H->
next=F;
H=H->
next;
returnFP;
Partition*New_Process(Partition*list,Partition*FP)
{//为新的进程分配资源
Partition*H,*P,*H1;
intSize,Name,L;
H1=FP->
H=H->
请输入新文件的名称和大小(整数):
%d%d"
Name,&
Size);
while(H)
H)//表目已查完,无法分配
\n已无空闲盘区,本次无法分配!
returnlist;
else{
if(H->
IsUse==0)//空表目
//if(H->
Par_Size>
=Size)//大小满足,空闲分区大小>
要分配的大小
if(H->
=Size)//大小满足,
{
booltemp=false;
if((H->
Par_Size-Size)<
=MAX_SEGMENT){//空闲分区大小-要分配的大小<
碎片值,会产生碎片,将整个盘块大小分配出去,
Size=H->
Par_Size;
//分配的大小为整个盘块
temp=true;
//会产生碎片
}
//其他情况就分配大小为请求大小,不会产生碎片,
L=H->
Addr;
//保存空闲分地址
if(temp){
printf("
该次分配会产生碎片,将整个盘区大小%d分配出去!
Size);
}else{
该次分配不会产生碎片"
}
break;
}
//否则,继续往下查找
if(H)
if(H->
Size)//大小满足,空闲分区大小》要分配的大小
P=(structPartition*)malloc(sizeof(structPartition));
//分配新的表目,处理一条数据,分配一次内存
P->
IsUse=1;
Addr=L;
//指向空闲分区地址
next=H;
//修改指针
H->
pri->
next=P;
pri=H->
pri;
pri=P;
Par_Size=Size;
//分配大小为要请求分配的大小
Par_No=Name;
//名称
Par_Size-=Size;
//修改空闲分区,H所指区块大小减Size
Addr+=Size;
//H所指区块地址加Size
}else
//大小相等的,把当前表项设置空表目
while(H1)
if(H1->
IsUse==0)
{
H1->
//保存已分配地址
//在已分配表中设置为已分配
break;
}
H1=H1->
}else
所申请资源已大过系统所拥有的,请重新输入!
\n"
Partition*Reclaim(Partition*list,Partition*FP)
{//结束作业,资源回收,No为作业名,回收内存
Partition*H1,*H2,*H3,*HF;
//H1为释放区,H2为后分区,H3为前分区
intNo;
//作业名
H1=list;
HF=FP;
//可有可无?
H1=H1->
HF=FP->
请输入您想结束的文件名:
%D"
No);
while(HF)//对已分配表进行操作
if(HF->
Par_No==No)
HF->
//标志为空表目
break;
//这时保存着HF所指分区的信息
HF=HF->
HF)//如果找不到该作业,则提示出错
所输入的文件名称不正确,请重新输入!
else{
while(H1)//对空闲表进行操作
printf("
回收成功"
H2=H1->
//后分区
H3=H1->
//前分区
if(H2&
&
H2->
IsUse==0)//后接分区为空闲
if(H2->
next==NULL)//判断后接分区是否为尾结点
Par_Size+=H2->
//把H2合并到H1
free(H2);
已回收%d大小盘区"
H1->
}else//后分区不为空闲,表示已经被使用
next=H2->
H2->
next->
pri=H1;
if(H3&
H3->
IsUse==0)//前分区为空闲分区,则合并去前分区
H3->
Par_Size+=H1->
next=H1->
next!
=NULL)//若H1为尾结点
pri=H3;
free(H1);
voidPrint(Partition*list,Partition*FP)
{//输出已分配分区和空闲分区
Partition*H1,*H2;
H1=list->
H2=FP;
H2=H2->
****************已分配盘块表*******************\n"
分区序号大小始址状态\n"
while(H2)
%d%d%d"
H2->
Par_No,H2->
Par_Size,H2->
Addr);
if(H2->
IsUse==1)
已分配\n"
else
空表目\n"
H2=H2->
**************************************************\n"
****************总的空闲盘块表*******************\n"
while(H1)
Par_No,H1->
Par_Size,H1->
if(H1->
H1=H1->
voidMain_Print(Partition*list,Partition*FP)
{//主入口函数,进行菜单选择
intop;
while
(1)
\n主菜单\n"
1.分配\n"
2.回收\n"
3.查看分配状态\n"
4.退出系统\n"
\n请选择:
scanf("
op);
switch(op)//根据输入,选择分支方向
case1:
New_Process(list,FP);
case2:
Reclaim(list,FP);
case3:
Print(list,FP);
case4:
default:
\n选择错误,请重新选择!
if(op==4)
//退出循环
/*************************************
下面是位示图方法
*************************************/
intWST[256];
空闲区结构体定义
start_location空闲区对象变量的开始位置
free_number空闲区块数目
next指向下一个空闲区的指针
**************************************/
typedefstructnode{
intstart_location;
intfree_number;
structnode*next;
}free_link;
申请空间作业结构体定义
office[]作业名
begin_location作业申请空间后的开始位置
office_number作业申请空间区的数目
next指向下一个申请空闲区的作业指针
typedefstructlink{
charoffice[20];
intbegin_location;
intoffice_number;
structlink*next;
}office;
/**************************************
相关位示图操作的结构体定义
p空间区链表指针
q作业链表指针
***************************************/
typedefstruct{
free_link*p;
office*q;
}work;
/***************************************
程序菜单
****************************************/
voidmenu(){
文件的存取和回收\n"
1--分配文件\n"
2--回收文件\n"
3--退出\n\t"
请输入选项:
"
置空位示图
进行初始化
voidzero_wst(){
256;
i++)
WST[i]=0;
/****************************************
位示图输出显示
将初始化或者申请或者回收后的位示图进行显示
*****************************************/
voidprint_wst(intWST[256]){
inti,j=0;
%3s"
"
16;
%3d"
i);
0);
i++){
j++;
WST[i]);
if(j%16==0&
i!
=0&
j!
=256){
j/16);
已经申请空间的作业相关情况输出显示
包括:
作业名
申请空间的开始位置和截至位置
voidprint_office(work*w){
q=w->
q;
q=q->
if(q!
=NULL){
已有文件:
while(q!
\t%s:
%d-%d\n"
q->
office,q->
begin_location,q->
begin_location+q->
office_number-1);
q=q->
位示图操作的初始化
空闲区链表的初始化
作业链表的初始化
**************************