0
空闲块数k
1
空闲块号1
2
空闲块号2
K
空闲块号k
当第一项容为“0〞时,则第二项起指出的空闲块是最后一组。
(2)现模拟UNI*系统的空闲块成组,假定共有8块可供使用,每3块为一组,则空闲块成组的初始状态为:
开场时,空闲块号是顺序排列的,但经假设干次的分配和归还操作后,空闲块的就未必按序排列了。
用二维数组A:
array[0…M-1]ofarray[0…n-1]来模拟管理磁盘空间,用A[i]表示第I块,第0块A[0]作为专用块。
(3)成组的分组情况记录在磁盘物理块中,为了查找情况,必须把它们读入主存,故当磁盘初始化后,系统先将专用块容复制到主存中。
定义一个数组MA存放专用块容,即MA:
=A[0]。
申请一块磁盘空间时,查MA,从中找出空闲块号,当一组的空闲块只剩第一块时,则应把该块中指出的下一组的空闲块数和块号复制到专用块中,然后把该块分配给申请者。
当一组的空闲块分配完后则把专用块容〔下一组情况〕复制到主存,再为申请者分配。
分配算法如图6-1。
图6-1采用成组的分配算法
(4)归还一块时给出归还的块号,叵当前组不满规定块数时,将归还块登记入该组;假设当前组已满,则另建一新组,这时归还块作为新一组的第一块,应把主存中登记的一组情况MA复制到归还块中,然后在MA重新登记一个新组。
归还一块的算法如图6-2。
图6-2采用成组的回收算法
(5)设计分配和归还磁盘空间的程序,能显示或打印分配的磁盘空间的块号,在完成一次分配或归还后能显示或打印各空闲块组的情况〔各组的空闲块数和块号〕。
本实习省去了块号与物理地址之间的转换工作,而在实际的系统中必须进展块号与物理地址的转换工作。
(6)运行你所设计的程序,假定空闲块的初始状态如提示〔2〕,现先分配4块,再依次归还第2块和第6块。
把执行后分配到的块号依次显示或打印出来,且显示或打印空闲块组的情况。
在上次执行的根底上继续分配3块,然后归还第1块,再申请5块,显示或打印依次分配到的块号及空闲块组情况。
四、相关数据构造及说明
structfreeblock{
intFBbegin;//起始空闲块号
intnum;//空闲块数
charstate;//状态
structfreeblock*ne*t;}
structfiletowrite{
charname[10];//文件名
intsize;//文件大小
intaddr_cylinder;//装入磁盘的首地址_柱面号
intaddr_track;//装入磁盘的首地址_磁道号
intaddr_note;//装入磁盘的首地址_物理记录号
structfiletowrite*ne*t;}
六、源代码及注释
1、题一源代码:
*include
*include
intgetmalloc()//分配磁盘空间{
intflag=0;
structfreeblock*p=FBhead;
structfiletowrite*File;
File=(structfiletowrite*)malloc(sizeof(structfiletowrite));
printf("输入要装入的文件名:
");
scanf("%s",File->name);
printf("输入所需的磁盘空间大小:
");
scanf("%d",&File->size);
for(p=FBhead->ne*t;p!
=NULL;p=p->ne*t)
if((File->size)<=(p->num))//分配空间
{
flag=1;
File->addr_cylinder=((p->FBbegin)/6)/20;
File->addr_track=((p->FBbegin)/6)%20;
File->addr_note=(p->FBbegin)%6;
File->ne*t=Filehead->ne*t;//参加文件链表
Filehead->ne*t=File;
if((File->size)<(p->num))//修改该快的起始地址和块数
{
p->FBbegin=p->FBbegin+File->size;
p->num=p->num-File->size;}
elsep->state='U';
break;}
if(flag==0)
printf("抱歉!
目前没有足够的磁盘空间分配给该文件.\n");
else{
printf("分配磁盘成功!
\n该文件的物理地址:
\n柱面号\t磁道号\t物理块号\n");
printf("%d\t%d\t%d\n",File->addr_cylinder,File->addr_track,File->addr_note);}}
intdeletelfree()//回收磁盘空间{
charname[10];intflag=0;
structfiletowrite*p;
printf("输入要删除的文件名:
");
scanf("%s",&name);
for(p=Filehead;p->ne*t!
=NULL;p=p->ne*t)
{
if(strcmp(p->ne*t->name,name)==0)//找到该文件
{
flag=1;
intfunion=0,nunion=0;
intm=p->ne*t->addr_cylinder;
intn=p->ne*t->addr_track;
intk=p->ne*t->addr_note;
intaddr=(m*20+n)*6+k;//起始空闲块号
inttail=p->ne*t->size+addr;
structfreeblock*pnode,*qnode,*tnode,*snode;
pnode=FBhead->ne*t;
while(pnode!
=NULL)//先考虑和后面的局部或许有合并的情况
{
if((pnode->FBbegin)==tail)
{
pnode->FBbegin=addr;
pnode->num=pnode->num+p->ne*t->size;
nunion=1;
break;}
pnode=pnode->ne*t;}
qnode=FBhead->ne*t;
while(qnode!
=NULL)//再考虑是否和前面的可以合并
{
if((qnode->FBbegin+qnode->num)==addr)
{
if(nunion==0)
{
qnode->num=qnode->num+p->ne*t->size;
funion=1;
break;}
else
{
qnode->num=qnode->num+pnode->num;t
node=FBhead;
while(tnode->ne*t!
=pnode)
tnode=tnode->ne*t;
tnode->ne*t=pnode->ne*t;
free(pnode);
funion=1;
break;
}
}
qnode=qnode->ne*t;}
if(funion==0&&nunion==0)//假设没有和前面的或后面的进展合并,则新建一个表目
{
snode=(structfreeblock*)malloc(sizeof(structfreeblock));
snode->FBbegin=addr;
snode->num=p->ne*t->size;
snode->state='F';
if(FBhead->ne*t==NULL)
{
FBhead->ne*t=snode;
snode->ne*t=NULL;
}
else
{
snode->ne*t=FBhead->ne*t;
FBhead->ne*t=snode;}}
structfiletowrite*q;
q=p->ne*t;//除该文件
p->ne*t=p->ne*t->ne*t;
free(q);break;}}
if(flag==0)
printf("没有该文件!
\n");
else{
printf("文件删除成功!
\n");}
intdispfree()//显示磁盘空闲区表
{
inti=1;
structfreeblock*p=FBhead;
printf("\n磁盘空闲区表\n");
printf("序号\t起始空闲块号\t空闲块个数\t状态\n");
for(p=FBhead->ne*t;p!
=NULL;p=p->ne*t)
{
if((p->state)=='F')
printf("%d\t%d\t\t%d\t\t未分配\n",i++,p->FBbegin,p->num);
else
printf("%d\t\t\t\t\t空表目\n",i++);}}
intdispfile()
{
charname[10];
structfiletowrite*p=Filehead;printf("输入要查看的文件名:
");
scanf("%s",&name);
for(p=Filehead->ne*t;p!
=NULL;p=p->ne*t)
{
if(strcmp(p->name,name)==0){
printf("该文件的物理地址:
\n柱面号\t磁道号\t物理块号\n");
printf("%d\t%d\t%d\n",p->addr_cylinder,p->addr_track,p->addr_note);break;}}
if(p==NULL)
printf("没有该文件!
\n");}
intmain(){
intn,i,A[MA*],B[MA*];//A[MA*]表示起始空闲块号,B[MA*]表示空闲块个数
charch;
structfreeblock*pnew;
FBhead=(structfreeblock*)malloc(sizeof(structfreeblock));
FBhead->ne*t=NULL;
printf("输入磁盘空闲区个数:
");
scanf("%d",&n);
for(i=1;i<=n;i++){
pnew=(structfreeblock*)malloc(sizeof(structfreeblock));
pnew->ne*t=NULL;
pnew->ne*t=FBhead->ne*t;
FBhead->ne*t=pnew;
printf("起始空闲块号:
");
scanf("%d",&pnew->FBbegin);
printf("空闲块个数:
");
scanf("%d",&pnew->num);pnew->state='F';pnew=pnew->ne*t;}
Filehead=(structfiletowrite*)malloc(sizeof(structfiletowrite));
Filehead->ne*t=NULL;
do{
system("cls");
printf("\n\t\t**********主菜单**********\n\n");
printf("\t\t\t1.新建文件\n");
printf("\t\t\t2.删除文件\n");
printf("\t\t\t3.查看磁盘\n");
printf("\t\t\t4.查看文件\n");
printf("\t\t\t5.退出\n");printf("请选择:
");
scanf("%c",&ch);
switch(ch){
case'1':
getmalloc();system("pause");break;
case'2':
deletelfree();system("pause");break;
case'3':
dispfree();system("pause");break;
case'4':
dispfile();system("pause");break;
case'5':
e*it
(1);break;
default:
printf("输入错误!
请重新输入.\n");
}
printf("\n");
getchar();}
while(ch!
=4);
return0;
2、题二源代码:
*include
*include
voidInitbitmap(intmap[8][8]){
intcylinder,track,sector;
charchoice='Y';
printf("初始化位视图...\n");
while(choice=='y'||choice=='Y'){
printf("柱面号:
");
scanf("%d",&cylinder);
printf("磁道号:
");
scanf("%d",&track);
printf("物理记录号:
");
scanf("%d",§or);
map[cylinder][4*track+sector]=1;
printf("contiune");
getchar();
scanf("%c",&choice);}}
voidallocate(intmap[8][8]){
inti,j;
intflag=0;
intcylinder,track,sector;
for(i=0;i<8;i++)
{for(j=0;j<8;j++)
if(map[i][j]==0)
{
map[i][j]=1;
flag=1;
break;
}
if(flag==1)break;
}
if(flag==1)
{
cylinder=i;track=j/4;sector=j%4;
printf("分配到的柱面号、磁道号、物理记录数");
printf("%d\t%d\t%d",cylinder,track,sector);
printf("\n");}
elseprintf("空间缺乏,分配失败!
");}
voidreclaim(intmap[8][8])
{intcylinder,track,sector;
printf("柱面号:
");
scanf("%d",&cylinder);
printf("磁道号:
");
scanf("%d",&track);
printf("物理记录号:
");
scanf("%d",§or);
if(map[cylinder][4*track+sector]==0){
printf("此块为未分配块!
回收出错!
");
getchar();}
else{
map[cylinder][4*track+sector]=0;
printf("回收块对应的字节号:
%4d\t位数:
%4d\n",cylinder,4*track+sector);}}
voidmain(){
intbitmap[8][8];inti,j;intchoice;
or(i=0;i<8;i++)for(j=0;j<8;j++)
bitmap[i][j]=0;Initbitmap(bitmap);
while
(1){
printf("\n请输入选择:
");
printf("1--分配,2---回收,3--显示位示图,0--退出\n");
scanf("%d",&choice);switch(choice){
case1:
allocate(bitmap);break;
case2:
reclaim(bitmap);break;
case3:
for(i=0;i<8;i++)
{for(j=0;j<8;j++)
printf("%8d",bitmap[i][j]);
printf("\n");}
break;
case0:
e*it(0);
default:
printf("错误选择!
");break;}}}
3、第三题源程序:
*include
intMA[4];/*空闲块数组*/
intA[9][4]={{3,1,2,3},{3,4,5,6},{0,0,0,0},{0,0,0,0},{3,0,7,8},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};/*磁盘空间*/
intmark[9];/*存放已分配的块*/
intNo=0;/*已分配的块数*/
voiddisplay1()
{inti,j,temp,count,No=0;
if(MA[1]!
=0)
{i=MA[0];
printf("\ngroup1:
");
for(j=1;j<=i;j++)
{printf("%d",MA[j]);
mark[++No]=MA[j];}
temp=MA[1];
count=2;
while(A[temp][1]!
=0)
{printf("\ngroup%d:
",count);
i=A[temp][0];
for(j=1;j<=i;