UNIX磁盘空间管理.docx
《UNIX磁盘空间管理.docx》由会员分享,可在线阅读,更多相关《UNIX磁盘空间管理.docx(13页珍藏版)》请在冰豆网上搜索。
UNIX磁盘空间管理
实验报告
课程:
操作系统
班级:
姓名:
学号:
成绩:
指导教师:
实验日期:
实验密级:
预习程度:
实验时间:
仪器组次:
必修/选修:
实验序号:
实验名称:
UNIX磁盘空间管理算法
实验目的与要求:
目的:
掌握UNIX外存空间管理中的分组链接算法。
要求:
1.在程序运行的结果中应包含磁盘块的分配与回收操作。
2.可根据输入的文件名、文件大小进行模拟磁盘分配,并在每次分配与回收后显示分配与回收是否成功,以及分配、回收的磁盘块号。
3.在程序执行过程中,至少应包含分配不成功一次的信息。
4.可以查看当前磁盘块的使用情况:
哪些块空闲,哪些块被哪些文件占用。
实验仪器:
名称
型号
数量
微机
1
实验三UNIX磁盘空间管理算法
一、实验内容
编写C语言程序,模拟UNIX磁盘空间管理中使用的分组链接法。
1.定义一个记录磁盘块号的堆栈S—free[10],以及记录栈中现有磁盘块数的变量S—nfree。
2.定义一个由40个元素构成的结构数组block[40]用作磁盘块存放。
structsize
{intblocl[10];
}
structblocd
{structsizea[10];
//用于在空闲磁盘块号链中存放磁盘块号
}block[40];
3.假设系统中文件的最大容量为100个磁盘块,且最多只有5个文件,定义一个由5个元素构成的结构数组file[5]用于记录各个文件占用的磁盘块,。
structFile
{intfileblocd[100];
//用于记录分别分配给文件的磁盘块号
}file[5];
4.编写函数init()完成空闲磁盘块号堆栈、空闲磁盘块号队列及记录文件占用磁盘块状态的file结构数组。
5.编写函数alloc(fileno,blockd),完成磁盘块的分配操作。
其中的参数fileno为文件序号,用于指定需要分配的文件。
6.编写函数free(fileno),完成文件占用磁盘块的释放操作。
其中的参数fileno为文件序号,用于指定需要释放磁盘块的文件。
7.编写main()函数完成下列操作:
•调用init()函数完成初始设置。
•从终端输入命令,控制磁盘块的分配与回收操作。
二、实验要求
1.在程序运行的结果中应包含磁盘块的分配与回收操作。
2.可根据输入的文件名、文件大小进行模拟磁盘分配,并在每次分配与回收后显示分配与回收是否成功,以及分配、回收的磁盘块号。
3.在程序执行过程中,至少应包含分配不成功一次的信息。
4.可以查看当前磁盘块的使用情况:
哪些块空闲,哪些块被哪些文件占用。
三、实验思路
成组链接法:
按照题目要求,首先把文件存储设备中的所有空闲快按每10块分为一组,每组的第一块用来存放前一组中各块的块号和总块数。
按照题目要求进行分组之后,系统可根据申请者的要求进行空闲块的分配和回收。
1.首先确定结构体:
1)用作磁盘块存放的结构数组:
structsize
{intblocl[10];
}
structblocd
{structsizea[10];
//用于在空闲磁盘块号链中存放磁盘块号
}block[40];
每10块为一组,分为40组。
每块中有10个空闲块。
2)各文件占用的磁盘块结构体:
structfile{
intfileblocd[100];
intlength;
}file[5];
每个文件的最大容量是100个磁盘块fileblocd[100],最多5个文件,length表示文件长度。
2.确定全局变量:
ints_free[10];//记录磁盘块号的堆栈
ints_nfree=0;//记录栈中现有磁盘块数的变量
intn;//分配或回收的文件号
intm;//分配的文件大小
intCurrent=39;//表示当前外存最后组号
3.初始化函数init()
在初始化时,需要记录每组空闲块的块号,并且将最后一组空闲块的块号信息送入内存数组s_free[10]中,因为分配时是从最后一组开始的。
在此,我把每组的最后一块的10个空间用来记录这一组空闲块的块号,如第一组的最后一块十个数0-9:
block[1].a[9].blocl[0]=0,block[1].a[9].blocl[1]=1······block[1].a[9].blocl[9]=9分别表示这一组的十个空闲块块号是0-9。
此外,在初始化时,还需要将文件块号的数组清零:
for(intq=0;q<=4;q++){//文件块号的数组清零
for(intp=0;p<=99;p++){
file[q].fileblocd[p]=0;
}
file[q].length=0;
}
完成之后,需要调整当前外存最后组号和栈中现有的磁盘块数。
4.分配函数voidalloc(intm_alloc,intn_alloc),其中m_alloc为需要分配的块数,n_alloc为文件号:
在分配时,按照后进先出的原则,分配程序在取走s_nfree所指的块号后,做s_nfree=s_nfree-1的操作。
分配时以10个空闲块为一组进行分配,当文件所需要的块数不足10个时,直接分配,并将剩余的空闲块保存在内存堆栈中,以便于下次分配或释放使用;当文件所需要的块数超过10个时,每分配完10个(s_nfree==-1时),再从外存中读取10个空闲块进入内存堆栈进行分配,剩余部分保存在内存堆栈中。
具体实现如下:
for(inti=0;iif(s_nfree==-1){
for(intk=0;k<=9;k++){
s_free[k]=block[Current].a[9].blocl[k];
block[Current].a[9].blocl[k]=0;
}
Current--;
s_nfree=9;
}
file[n_alloc].fileblocd[i]=s_free[s_nfree];
s_nfree--;
}
5.回收函数free(intm_free,intn_free),其中m_free表示需要回收文件的长度,n_free表示需要回收的文件号:
在回收空闲块时,同样利用文件管理堆栈进行,首先将需要回收的空闲块释放到内存堆栈中,把需要回收的物理块号放入s_nfree+1的位置处,再做s_nfree++操作,当内存堆栈满了之后(s_nfree==9时),表示回收结束,并将文件长度置为0。
如果此时还有新的物理块需要回收,将刚刚回收的10个块号写入外存中,然后将s_nfree置为-1,并将Current+1另起一个新堆栈。
具体实现如下:
for(inti=0;iif(s_nfree==9){
Current++;
for(intk=0;k<=9;k++){
block[Current].a[9].blocl[k]=s_free[k];
s_free[k]=0;
}
s_nfree=-1;
}
s_free[s_nfree+1]=file[n_free].fileblocd[i];
printf("%d",file[n_free].fileblocd[i]);
file[n_free].fileblocd[i]=0;
s_nfree++;
}
6.main()函数:
调用init()函数初始化,并设计目录(分配、回收、查看、退出),控制磁盘的分配和回收,在此要注意防止用户的非法输入。
四、运行结果
五、实验体会
通过这次实验,我对外存空间管理的成组链接法有了更深刻的了解,充分掌握了成组链接法的工作原理,对于互斥操作也有了进一步了解。
附录:
#include
structsize{//每个块10个
intblocl[10];
};
structblock{//每组10个块,共40组
structsizea[10];
}block[40];
structfile{
intfileblocd[100];
intlength;//文件长度
}file[5];
ints_free[10];//记录磁盘块号的堆栈
ints_nfree=0;//记录栈中现有磁盘块数的变量
intn;//分配或回收的文件号
intm;//分配的文件大小
intCurrent=39;//表示当前外存最后组号
voidinit();
voidshow();
voidalloc(intm_alloc,intn_alloc);
voidfree(intm_free,intn_free);
voidinit()//初始化函数
{
for(inti=0;i<=39;i++){//将每组的块号放到最后一块的10个数中
for(intk=0;k<=9;k++){
block[i].a[9].blocl[k]=i*10+k;
}
}
for(intq=0;q<=4;q++){//文件块号的数组清零
for(intp=0;p<=99;p++){
file[q].fileblocd[p]=0;
}
file[q].length=0;
}
for(intb=0;b<=9;b++){//将最后一组的信息送入内存
s_free[b]=block[Current].a[9].blocl[b];
block[Current].a[9].blocl[b]=0;
}
Current--;
s_nfree=9;
}
voidshow()//查看
{
intb=0;
printf("\n外存的空闲块号为:
\n");
if(s_nfree==-1)Current--;
for(inti=0;i<=Current;i++){
for(intk=0;k<=9;k++){
if(block[b].a[9].blocl[1]!
=0)
printf("%d",block[i].a[9].blocl[k]);
else
gotonext;
}
}
next:
printf("\n内存缓冲区中的空闲块号:
\n");
if(s_nfree==-1){
Current++;
for(intq=0;q<=9;q++)printf("%d",block[Current].a[9].blocl[q]);
}
else
for(intq=0;q<=s_nfree;q++)printf("%d",s_free[q]);
printf("\n未分配空间的文件:
\n");
for(intp=0;p<=4;p++){
if(file[p].length==0)
printf("%d",p);
}
printf("\n已分配空间的文件:
\n");
for(intq=0;q<=4;q++){
if(file[q].length!
=0)
printf("%d",q);
}
printf("\n");
}
voidalloc(intm_alloc,intn_alloc)//分配函数
{
file[n_alloc].length=m_alloc;
if(m_alloc>=Current*10-1+s_nfree)
printf("外存空间不足\n");
else{
for(inti=0;iif(s_nfree==-1){
for(intk=0;k<=9;k++){
s_free[k]=block[Current].a[9].blocl[k];
block[Current].a[9].blocl[k]=0;
}
Current--;
s_nfree=9;
}
file[n_alloc].fileblocd[i]=s_free[s_nfree];
s_nfree--;
}
printf("文件%d分配的块号:
\n",n_alloc);
for(intq=0;qprintf("\n文件分配成功!
\n");
}
}
voidfree(intm_free,intn_free)//回收函数
{
printf("文件%d释放的块号:
\n",n_free);
for(inti=0;iif(s_nfree==9){
Current++;
for(intk=0;k<=9;k++){
block[Current].a[9].blocl[k]=s_free[k];
s_free[k]=0;
}
s_nfree=-1;
}
s_free[s_nfree+1]=file[n_free].fileblocd[i];
printf("%d",file[n_free].fileblocd[i]);
file[n_free].fileblocd[i]=0;
s_nfree++;
}
printf("\n文件释放成功!
\n");
file[n_free].length=0;
}
intmain()
{
intx=0;
intCurrent=39;
init();
while(true){
printf("请选择操作:
1、分配2、回收3、查看4、退出\n");
scanf("%d",&x);
while(x<=0||x>=5){
printf("输入错误,请重新输入:
1、分配2、回收3、查看4、退出\n");
scanf("%d",&x);
}
if(x==4)return-1;
if(x==3){
show();
continue;
}
printf("请输入文件号(0--4):
");
scanf("%d",&n);
while(n<0||n>=5){
printf("输入错误,请重新输入:
\n请输入文件号(0--4):
");
scanf("%d",&n);
}
switch(x)
{
case1:
while(file[n].fileblocd[0]!
=0){
printf("该文件空间未释放!
\n请重新输入文件号:
");
scanf("%d",&n);
}
printf("请输入所需分配的块数(0--100):
");
scanf("%d",&m);
while(m<=0||m>=100){
printf("输入错误,请重新输入:
\n请重新输入所需分配的块数(0--100):
");
scanf("%d",&m);
}
alloc(m,n);
break;
case2:
while(file[n].fileblocd[0]==0){
printf("该文件空间未分配!
\n请重新输入合法的文件号(0--4):
");
scanf("%d",&n);
}
free(file[n].length,n);
break;
}
}
}