0
空闲块数k
1
空闲块号1
2
空闲块号2
K
空闲块号k
当第一项容为“0”时,则第二项起指出的空闲块是最后一组。
(2)现模拟UNIX系统的空闲块成组,假定共有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*next;}
struct filetowrite {
char name[10];//文件名
int size;//文件大小
int addr_cylinder;//装入磁盘的首地址_柱面号
int addr_track;//装入磁盘的首地址_磁道号
int addr_note;//装入磁盘的首地址_物理记录号
struct filetowrite *next; }
六、源代码及注释
1、题一源代码:
#include
#include
int getmalloc()//分配磁盘空间 {
int flag=0;
struct freeblock *p=FBhead;
struct filetowrite *File;
File=(struct filetowrite *)malloc(sizeof(struct filetowrite));
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; }
else p->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); } }
int deletelfree()//回收磁盘空间 {
char name[10]; int flag=0;
struct filetowrite *p;
printf("输入要删除的文件名:
");
scanf("%s",&name);
for(p=Filehead;p->next!
=NULL;p=p->next)
{
if(strcmp(p->next->name,name)==0)//找到该文件
{
flag=1;
int funion=0,nunion=0;
int m=p->next->addr_cylinder;
int n=p->next->addr_track;
int k=p->next->addr_note;
int addr=(m*20+n)*6+k;//起始空闲块号
int tail=p->next->size+addr;
struct freeblock *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; t
node=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=(struct freeblock *)malloc(sizeof(struct freeblock));
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; } }
struct filetowrite *q;
q=p->next;//除该文件
p->next=p->next->next;
free(q); break; } }
if(flag==0)
printf("没有该文件!
\n");
else {
printf("文件删除成功!
\n"); }
int dispfree()//显示磁盘空闲区表
{
int i=1;
struct freeblock *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++); } }
int dispfile()
{
char name[10];
struct filetowrite *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"); }
int main() {
int n,i,A[MAX],B[MAX];//A[MAX]表示起始空闲块号,B[MAX]表示空闲块个数
char ch;
struct freeblock *pnew;
FBhead=(struct freeblock *)malloc(sizeof(struct freeblock));
FBhead->next=NULL;
printf("输入磁盘空闲区个数:
");
scanf("%d",&n);
for(i=1;i<=n;i++) {
pnew=(struct freeblock *)malloc(sizeof(struct freeblock));
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=(struct filetowrite *)malloc(sizeof(struct filetowrite));
Filehead->next=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':
exit
(1);break;
default:
printf("输入错误!
请重新输入.\n");
}
printf("\n");
getchar(); }
while(ch!
=4);
return 0;
2、题二源代码:
#include
#include
void Initbitmap(int map[8][8]) {
int cylinder,track