您的位置:首页 > 运维架构 > Linux

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

2016-11-14 12:18 232 查看
 首次适应算法:

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

  题目要求:

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

[提示]:

(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->addre
4000
ss+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合分配一个8K给homework6



回收homework3

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息