当前位置:文档之家› 3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理

3用C语言模拟实现可变式分区存储管理
3用C语言模拟实现可变式分区存储管理

试验三:用C语言模拟实现可变式分区存储管理

一、試驗目标:

1、通过编写可变式分区存储管理的C语言程序,使学生加强对可变式分区存储管理的认识。

2、掌握操作系统设计的基本原理、方法和一般步骤。

二、試驗内容:用C語言編寫一個实现可变式的分区管理的模擬程序。

*复习相关的知识:

1、分区管理的原理:将存储器划分成若干段大小固定的区域,一个区域里只能运行一个程序,程序只能在其自身所在的分区中活动。

2、固定式分区管理的原理:区域大小及起始地址是固定的。一个分区只能存放一个程序。需要设置一个分区说明表来标明内存的使用状态。根据分区说明表来给程序分配相应的区域。由于程序不可能刚刚占有一个分区的大小,这样就会在一个分区之中留下零头,造成了极大的浪费。

3、可变式分区管理的原理:区域的大小及起始地址是可变的,根据程序装入时的大小动态地分配一个区域。保证每个区域之中刚好放一个程序。这样可以充分地利用存储空间,提高内存的使用效率。如果一个程序运行完毕,就要释放出它所占有的分区,使之变成空闲区。这样就会出现空闲区与占用区相互交错的情况。这样就需要P表,F表来分别表示内存的占用区状态与空闲区的状态。

*确定该系统所使用的数据结构:

我们可以把内存表示为一个数组的形式。这个数组中的每一个单元都是一个无符号的字符型的数据类型。这样一个单元刚好占用一个字节的大小。这一个字节的地址可以用它在此数组中的下标来表示。如果一个程序占用了一定的区域,那么这个区域的大小就可以用它占有的字节数的个数来表示。用C语言可以表述如下:

unsigned char memory[1024]

它就可以表示一个1K的内存空间。

为了实现可变式的分区管理,还需要设立两个表,一个是P表,一个是F表,它们分别表示内存的占用区状态。由于在该程序运行的过程之中需要不断地修改P表和F表,所以这两个表不适合于用数组的形式来表示;而应该使用单链表的形式。这样就要给单链表中的结点确立一个数据结构。很显然,P表中的每一个结点至少要包括以下的几项:占用的程序名、占用区的起始地址、占用区的大小、指向下一个结点的指针。F表中的结点可以不需要程序名这一项。但是为了统一起见,我们就统一地采用P 表中的这种结点的结构。可以用C语言描述如下:

struct node

{

char name[10];

int start, length;

struct node*next;

};

struct node*p, *f;

还要为它们确立一个初始的状态。这两个链表最好带有一个头结点。

p = (struct node *)malloc (sizeof(struct node));

p->next = NULL;

f = (struct node *) malloc (sizeof(struct node));

f->next = (struct node *)malloc (sizeof(struct node));

f->next ->start = 0;

f->next -> length = 1024;

f->next ->next = NULL;

*、实现分配与回收一个占用区的算法:

1、分配函数的执行过程:(按最佳分配法执行。)

#查找F表,在其中找到一个满足要求的空闲块。如果没有找到则提示用户。

#申请一个新的P结点,进行填写相关的数据,将其挂接在P表的尾部。

#修改原空闲区结点,并将其从F表中提出来。

#将修改后的结点插入到合适的位置,保证F表中的结点是按照地址空间的大小由小到大地进行排序。

#返回新生成P表结点的首地址。

2、回收函数的执行过程:

#查找P表,找到需要回收的程序的占用区结点。将它提出P表。

#生成一个新的空闲结点,填写它。表示新生成了一个空闲区。

#观察F表,看其中是否有旧的空闲区和新的空闲区相邻。如果有,就将它与新的空闲区结合点合并成一个大的空闲区。

#将新生成的空闲区结点插入到F表中的合适的位置。

三.试验要求:设计一个可变长分区的存储器分配程序。

四.试验报告要求

1.写出试验目的

2。写出试验要求

3。写出试验内容(包括可变长分区算法描述、实验结果及分析)

附录1:

分配函数(fenpei)和回收函数(free)的C语言源程序:

int fenpei(char *c, int room, struct node *p, *f)

{

struct node *p1, *f1,

*f2;/*f2是f1的跟随指针*/

f1 = f->next;f2 = f;

while (f1!=NULL)/*查找F表,看是否有满足条件的一个结点,如果没有则提示出错了*/

{

if (f1->length >=room)

break;

f1 = f1 -> next; f2 = f2->next;

}

if (f1 == NULL)

{

printf("no enough space!!!\n");

return (-1);

}/*定位到P表的末尾,生成一个新的结点,联接到后面。*/

p1 = p;

while(p1->next != NULL)

p1 = p1 ->next;

p1->next = (struct node *)malloc(sizeof(struct node));

p1 = p1->next ;

p1->length = room;

strcpy(p1->name, c);

p1->start = f1 -> start;

p1->next =

NULL;/*修改F表中被分配的节点*/

f1->length = f1->length - room;

f1->start = f1->start + room;

f2->next = f1 ->next;

if

(f1->length !=0)/*如果修改后的节点大小为0,则舍弃之。*/

{

f2 = f;

while((f2->next!=NULL)&&(f2->next->leng th<= f1->length))

f2 = f2 ->next;

f1 ->next = f2 ->next;

f2->next = f1;

}

return (p1->start) ;

}

struct node *free (char *c, struct node *p, *f)

{

struct node *p1, *p2, *f1, *f2, *f3;

p1 = p->next ;

p2 =

p;/*p2是p1是跟随指针*/

while(p1!= NULL)

/*按外界提供的程序名在P表中查找其结点,若没找到,则返回NULL*/

{

if (!(strcmp(p1->name,c))) break;

p1 = p1->next;

p2 = p2->next;

}

if (p1==NULL)

{

printf("No find the program!!!\n");

return (NULL);

}

p2->next = p1 -> next ;/*将找到的结点取出*/

f1 = (struct node *)malloc(sizeof(struct node));/*据此生成一个新的空闲结点*/

f1->start = p1 ->start ;

f1 ->length = p1 ->length;

/*在F表中依次观察各个结点,看是否能与此新的空闲结点合并*/

f2 = f->next;

f3 = f;

while (f2!= NULL)

{

if (f1->start + f1 ->length == f2->start)

{

f1->le ngth += f2->length;

f3->ne xt = f2->next;

f2 =

f2->next;

}

else if (f2->start + f2->length == f1->start )

{ f1->start = f2 ->start;

f1 ->length += f2->length;

f3 ->next = f2 ->next ;

f2 = f2->next;

}

else

{f2=f2->next ;f3 = f3->next;}

}

f2 = f;/*再寻找一个合适的地方插入此空闲结点*/

while((f2->next!=NULL)&&(f2->next->length<=f1->l ength))

f2 = f2->next;

f1->next = f2->next;

f2 ->next = f1;

return (f1);/*返回值*/

}

附录2:可变长分区存储分配完整程序

/*可变分区的模拟*/

#include

unsigned char memory[1024];

struct node

{

char name[5];

int start,length;

struct node *next;

} ;

struct node *p, *f, *pp,*ff;

/* 还要为它们确立一个初始的状态。这两个链表最好带有一个头结点。*/

struct node *free(char *c, struct node *p,struct node *f);

main()

{ int t=1,xz;

char name[5];

unsigned int size;

p = (struct node *)malloc (sizeof(struct node));

p->next = NULL;

f = (struct node *) malloc (sizeof(struct node));

f->next = (struct node *)malloc (sizeof(struct node));

f->next->start = 1;

f->next->length = 1024;

f->next->next = NULL;

printf("可变式内存管理模拟\n ");

while (t==1)

{

printf("1:运行进程;2:终止进程;3:退出请选择:");

scanf("%d",&xz);

switch (xz)

{ case 1:

{printf("请输入请求进程的进程名(<=5个字符):");

scanf("%s",name);

printf("请输入请求进程所需空间(起始可用内存1024):");

scanf("%d",&size);

fenpei(name,size,p,f);

print(); /*打印分配表空闲表*/

}

break;

case 2: {printf("请输入终止进程的进程名:");scanf("%s,%d",name);

ff=free(name,p,f );

print();/*打印分配表空闲表*/

}

break;

case 3: t=0;break;

}

}

}

/*打印分配表空闲表函数*/

print()

{ /*打印分配表*/

printf("分配表\n");

pp=p->next;

while (pp!=NULL)

{printf("%5s,%d,%d\n",pp->name,pp->start, pp->length);pp=pp->next;}

/*打印空闲表*/

printf("空闲表\n");

ff=f->next;

while (ff!=NULL)

{printf(" %d,%d\n",ff->start, ff->length);ff=ff->next;}

}

/*为进程分配空间函数*/

int fenpei(char *c, int room, struct node *p,struct node *f)

{ struct node *p1, *f1, *f2; /*f2是f1的跟随指针*/

f1 = f->next; f2 = f;

while (f1!=NULL) /*查找F表,看是否有满足条件的一个结点,如果没有则提示出错了*/

{if (f1->length >=room)

break;

f1 = f1->next; f2 = f2->next;}

if (f1 == NULL)

{ printf("没有足够的空间,不能实施分配!!!\n");

return (-1);

}

/*定位到P表的末尾,生成一个新的结点,联接到后面。*/

p1 = p;

while(p1->next != NULL)

p1 = p1->next;

p1->next = (struct node *)malloc(sizeof(struct node));

p1 = p1->next ;

p1->length = room/*-1*/;

strcpy(p1->name, c);

p1->start = f1->start;

p1->next = NULL; /*修改F表中被分配的节点*/

f1->length = f1->length - room;

f1->start = f1->start + room;

f2->next = f1->next;

if (f1->length !=0) /*如果修改后的节点大小为0,则舍弃之。*/ { f2 = f;

while((f2->next!=NULL)&&(f2->next->length<= f1->length))

f2 = f2 ->next;

f1->next = f2->next;

f2->next = f1; }

return (p1->start) ;

}

/*回收进程所占空间函数*/

struct node *free(char *c, struct node *p,struct node *f)

{

struct node *p1, *p2, *f1, *f2, *f3;

p1 = p->next ;

p2 = p; /*p2是p1是跟随指针*/

while(p1!= NULL)

/*按外界提供的程序名在P表中查找其结点,若没找到,则返回NULL*/

{

if (!(strcmp(p1->name,c))) break;

p1 = p1->next;

p2 = p2->next;

}

if (p1==NULL)

{

printf("没找到该进程!!!\n");

return (NULL);

}

p2->next = p1->next ; /*将找到的结点取出*/

f1 = (struct node *)malloc(sizeof(struct node));/*据此生成一个新的空闲结点*/ f1->start = p1->start ;

f1->length = p1->length;

/*在F表中依次观察各个结点,看是否能与此新的空闲结点合并*/

f2 = f->next;

f3 = f;

while (f2!= NULL)

{

if (f1->start + f1 ->length == f2->start)

{

f1->length += f2->length;

f3->next = f2->next;

f2 = f2->next;

}

else if (f2->start + f2->length == f1->start )

{

f1->start = f2 ->start;

f1 ->length += f2->length;

f3 ->next = f2 ->next ;

f2 = f2->next;

}

else {f2=f2->next ; f3 = f3->next;}

}

f2 = f; /*再寻找一个合适的地方插入此空闲结点*/

while ((f2->next!=NULL)&&(f2->next->length<=f1->length))

f2 = f2->next;

f1->next = f2->next;

f2->next = f1;

return (f1); /*返回值*/

}

相关主题
文本预览
相关文档 最新文档