成一组,最后一组可以不足N块,每组的第一块中登记了下一组空闲块的块数和块号,第
一组的块数和块号登记在专用块中,登记的格式如下:
当第一项内容为“0”时,则第二项起指出的空闲块是最后一组。
(2)现模拟UNlX系统的空闲块成组链接,假定共有8块可供使用,每3块为一组,则
空闲块成组链接的初始状态为:
空闲块的链接就未
开始时,空闲块号是顺序排列的,但经若干次的分配和归还操作后,
必按序排列了。
用二维数组A:
array[0∙∙∙M-1]Ofarray[0…n-1]来模拟管理磁盘空间,用A[i]表示第I
块,第O块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*next;}
StrUCtfiletowrite{
Charname[10];//文件名
intsize;//文件大小
intaddr_cylinder;//装入磁盘的首地址_柱面号intaddr_track;//装入磁盘的首地址_磁道号intaddr_note;//装入磁盘的首地址—物理记录号StrUCtfiletowrite*next;}
六、源代码及注释
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->next;p!
=NULL;p=p->next)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->next=Filehead->next;//加入文件链表
Filehead->next=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->next!
=NULL;p=p->next)
{
if(strcmp(p->next->name,name)==0)//找到该文件
{
flag=1;
intfunion=0,nunion=0;
intm=p->next->addr_cylinder;
intn=p->next->addr_track;
intk=p->next->addr_note;
intaddr=(m*20+n)*6+k;//起始空闲块号
inttail=p->next->size+addr;
structfreeblock*pnode,*qnode,*tnode,*snode;
pnode=FBhead->next;
while(pnode!
=NULL)//先考虑和后面的部分或许有合并的情况
{
if((pnode->FBbegin)==tail)
{
pnode->FBbegin=addr;pnode->num=pnode->num+p->next->size;
nunion=1;
break;}pnode=pnode->next;}qnode=FBhead->next;
while(qnode!
=NULL)//再考虑是否和前面的可以合并
{if((qnode->FBbegin+qnode->num)==addr)
{
if(nunion==0)
{
qnode->num=qnode->num+p->next->size;
funion=1;
break;}
else
{qnode->num=qnode->num+pnode->num;tnode=FBhead;
while(tnode->next!
=pnode)tnode=tnode->next;
tnode->next=pnode->next;
free(pnode);funion=1;
break;
}
}
qnode=qnode->next;}
if(funion==0&&nunion==0)//若没有和前面的或后面的进行合并,则新建一个表目
{
snode=(structfreeblock*)malloc(sizeof(structfreeblock));snode->FBbegin=addr;
snode->num=p->next->size;snode->state='F';
if(FBhead->next==NULL)
{
FBhead->next=snode;snode->next=NULL;
}
else
{snode->next=FBhead->next;
FBhead->next=snode;}}structfiletowrite*q;
q=p->next;//除该文件p->next=p->next->next;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->next;p!
=NULL;p=p->next)
{
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->next;p!
=NULL;p=p->next)
{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[MAX],B[MAX];//A[MAX]表示起始空闲块号,B[MAX]表示空闲块个数
charch;
structfreeblock*pnew;
FBhead=(structfreeblock*)malloc(sizeof(structfreeblock));
FBhead->next=NULL;
printf("输入磁盘空闲区个数:
");
scanf("%d",&n);
for(i=1;i<=n;i++){
pnew=(structfreeblock*)malloc(sizeof(structfreeblock));
pnew->next=NULL;
pnew->next=FBhead->next;
FBhead->next=pnew;
printf("起始空闲块号:
");
scanf("%d",&pnew->FBbegin);
printf("空闲块个数:
");
scanf("%d",&pnew->num);pnew->state='F';pnew=pnew->next;}Filehead=(structfiletowrite*)malloc(sizeof(structfiletowrite));Filehead->next=NULL;
do{
system("cls");
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':
exit
(1);break;default:
printf("输入错误!
请重新输入.\n");
}printf("\n");getchar();}while(ch!
=4);return0;
2、题二源代码:
#include#includevoidInitbitmap(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:
exit(0);
default:
printf("错误选择!
");break;}}}
3、第三题源程序:
#include
intMA[4];int
/*空闲块数组*/
A[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