操作系统(Linux)--首次适应法实现主存分配和回收

来源:互联网 发布:arrival to earth知乎 编辑:程序博客网 时间:2024/04/20 02:59

 首次适应算法:

       从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。


  题目要求:

在可变分区管理方式下采用首次适应算法实现主存分配和回收。

[提示]

(1) 可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存容量查看是否有足够的空闲空间,若有,则按需分配,否则,作业无法装入。假定内存大小为128K,初始状态见下图。空闲区说明表格式为:起始地址——指出空闲区的起始地址;长度——一个连续空闲区的长度;状态——有两种状态,一种是“未分配”状态,另一种是“空表目”状态。

(2) 采用首次适应算法分配。运行时,输入一系列分配请求和回收请求。


设计思路:

数据结构采用的是二叉树;

初始化,只有一个根节点,分为左右孩子,左孩子用来装入作业,

右孩子为空闲区



第一个数据表示地址,第二个表示长度,第三个表示状态

(因为0到5K分给了系统)



(自己画的图,没画图工具,凑哈看吧

 先分配一段5K到128K的区域,然后在删除14K到26K的区域,就形成了上图需要的初始化。然后可以进行一系列分配和回收操作。

 

   打印分区表的时候,只需遍历一遍二叉树,然后输出度为0的节点(没有孩子的节点)


#include <iostream>#include <stdio.h>using namespace std;int temp =0 ;typedef struct _BiTNode{     int address;//地址     int length;//长度     bool state;//状态     int homework;//作业号     struct _BiTNode *lchild;//右孩子     struct _BiTNode *rchild;//左孩子}BiTNode,*pBiTree;void Init_BiTree(pBiTree l)//初始化5K到123K区域{    l->address = 5;    l->length = 123;    l->state = 0;    l->homework = 0;    l->lchild = NULL;    l->rchild = NULL;    printf("init successful! \n");}int Print(pBiTree p){     printf("\n\t\t\t%d\t%d\t", p->address,p->length);     if(p->state == 1)         printf("Busy \t");     else          printf("Free  \t");     if(p->homework!=0)         printf("%d\n",p->homework);     else          printf("\n");}void PreOrder(pBiTree p)//先序遍历{     if(p!=NULL)      {        if(!p->lchild&&!p->rchild)             Print(p);//父节点        PreOrder(p->lchild);//左子节点        PreOrder(p->rchild);//右子节点       }}void Insert_PreOrder(pBiTree p,int length,int homework)//插入新作业{      if(p!=NULL)      {          if((p->state == 0)&&(length<p->length)&&(!p->rchild)&&temp==0)//判断节点是否有左右孩子,是否小于空闲区长度,是否状态为0(表示区域无作业运行)             {              pBiTree  x1 = new BiTNode;//进行插入,动态申请两个空间x1,x2              pBiTree  x2 = new BiTNode;              x1->homework = homework;//x1为作业              x2->homework = 0;//x2为空闲区              x1->address = p->address;//把原空闲的首地址给作业的首地址              x1->state = 1;//作业状态改为1,表示busy              x1->length = length;              x2->address=x1->address+length;//x2为新的空闲区的首地址与x1长度之和              x2->length=p->length-x1->length;              p->lchild=x1;              p->rchild=x2;              x2->state=0;              x1->lchild=NULL;              x1->rchild=NULL;              x2->lchild=NULL;              x2->rchild=NULL;              temp=1;}           else           {              Insert_PreOrder(p->lchild,length,homework);              Insert_PreOrder(p->rchild,length,homework);            }}}void Delect_PreOrder(pBiTree p,int homework)//遍历修改,变为空闲区{       if(p !=NULL)       {          if(p->homework==homework)           {             p->homework = 0;             p->state=0;}        Delect_PreOrder(p->lchild,homework);        Delect_PreOrder(p->rchild,homework);}}int main(){    BiTNode l;    Init_BiTree(&l);//初始化一段5k到128k的区域    printf("\n Init:\t address\tlength\tstate\tomeworkname\n");        PreOrder(&l);    //insert_homework1    temp = 0;    Insert_PreOrder(&l,5,1);    printf("\n Insert_homework1:\taddress\tlength\tstate\thowmeworkname\n");    PreOrder(&l);    //insert_homework3    temp=0;    Insert_PreOrder(&l,4,3);    printf("\n Insert_homework2:\taddress\tlength\tstate\thowmeworkname\n");    PreOrder(&l);    //insert_homework4    temp=0;    Insert_PreOrder(&l,12,4);    printf("\n Insert_homework2:\taddress\tlength\tstate\thowmeworkname\n");    PreOrder(&l);    //insert_homework3    temp=0;    Insert_PreOrder(&l,6,2);    printf("\n Insert_homework2:\taddress\tlength\tstate\thowmeworkname\n");    PreOrder(&l);    //delect_homework4    Delect_PreOrder(&l,4);    printf("\n delect_homework1:\taddress\tlength\tstate\thomeworkname\n");    PreOrder(&l);         cout<<"==========="<<endl;    cout<<"Init successful!"<<endl;    //insert_homework5    temp=0;    Insert_PreOrder(&l,32,5);    printf("\ninsert_homework3:\taddress\tlength\tstate\thomeworkname\n");    PreOrder(&l);    //insert_homework6    temp=0;    Insert_PreOrder(&l,8,6);    printf("\n Insert_homework2:\taddress\tlength\tstate\thowmeworkname\n");    PreOrder(&l);    //delect_homework3    Delect_PreOrder(&l,3);    printf("\n delect_homework1:\taddress\tlength\tstate\thomeworkname\n");    PreOrder(&l);    return 0;} 


实验结果:


首先分配了一段5k到128k的区域,长度为123K




然后再初始化5到32K区域




delete第4个作业,实现要求的初始化。




最后进行一些分配合回收操作:

分配一个32K的给homework5合分配一个8Khomework6





回收homework3



0 0