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

 首次适应算法:

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


  题目要求:

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

[提示]

(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



猜你喜欢

转载自blog.csdn.net/qq_23948283/article/details/53157143