资源描述
实用标准
操作系统实验报告
实验[ 1 ]:主存储器空间的分配和回收
姓 名: 何 浪
学 号: 201306080215
专业班级: 计本132
实验时间: 2015.5.31
报告时间: 2015.6.6
系 别: 计算机系
学 院: 电气与信息工程学院
实验3 主存储器空间的分配和回收
一、实验内容
主存储器空间的分配和回收。
二、实验目的
一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。主存的分配和回收的实现与主存储器的管理方式有关的,通过本实验帮助学生理解在可变分区管理方式下应怎样实现主存空间的分配和回收。
三、实验原理
模拟在可变分区管理方式下采用最先适应算法实现主存分配和回收。
(1)可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。例如:
0
5k
10k
14k
26k
32k
512k
操作系统
作业1
作业3
空闲区
作业2
空闲区
为了说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:
起 址
长 度
状 态
第一栏
14 K
12 K
未 分 配
第二栏
32 K
96 K
未 分 配
M
M
M
M
其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区。
(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。
(3) 采用最先适应算法(顺序分配算法)分配主存空间。
按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。当空闲区大于需要量时,一部分用来装入作业,另一部分仍为空闲区登记在空闲区说明表中。
由于本实验是模拟主存的分配,所以把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。
(4) 当一个作业执行结束撤离时,作业所占的区域应该归还,归还的区域如果与其它空闲区相邻,则应合成一个较大的空闲区,登记在空闲区说明表中。
(5) 请按最先适应算法设计主存分配和回收的程序。假设初始时主存中没有作业,现按下面序列进行内存的申请与释放:
作业1申请300K,作业2申请100K,作业1释放300K,作业3申请150K,
作业4申请30K, 作业5申请40K, 作业6申请60K, 作业4释放30K。
请你为它们进行主存分配和回收,把空闲区说明表的初值以及每次分配或回收后的变化显示出来或打印出来。
四、算法流程图
c
b
a
继续
输入
主界面
选择
查看作业
回收内存
申请内存
退出程序
开始
结束
N
d
Y
五、源程序及注释
#include<iostream>
using namespace std;
#include <list> //双向链表结构头文件
#define Residue 512 //除系统占用内存外的剩余内存
#define fst_free 0 //第一块空闲区的起至地址
#define fst_size 512 //第一块空闲区的大小
#include <stdio.h>
#include <stdlib.h> //清屏函数头文件
class Free //定义空闲区类
{
public:
Free(){};
Free(int s,int l)
{
start = s;
length = l;
}
int get_free(int length); //成员函数获取空闲分区
void free_task(int start,int length);
friend void print_free();
protected:
int start;
int length;
};
list<Free *> free_list; //声明空闲分区表
int Free::get_free (int size)
{
int start = -1;
list<Free *>::iterator it=free_list.begin();//查找适当的空闲分区 iterator:迭代器(游标)提供一种方法访问一个容器
bool find = false;
while(it!=free_list.end())
{
if((*it)->length>=size)
{
find=true;
start = (*it)->start;
if((*it)->length>size) //大于就分割把低地址分配出去
{
(*it)->start += size;
(*it)->length -= size;
}
else
free_list.erase(it); //等于就从空闲分区中删掉
break; //找到就跳出循环
}
it++;
}
return start;
}
void Free::free_task (int start,int length)
{
list<Free *>::iterator init_it,last_it; //查找要插入的位置
last_it = init_it;
list<Free *>::iterator it=free_list.begin();
while(it!=free_list.end())
{
if((*it)->start > start) break;
last_it = it;
it++;
}
bool link_prev=false;
bool link_next=false;
if(last_it!= init_it) //有前一个时
{
if((*last_it)->start+(*last_it)->length == start)
link_prev = true;
}
if(it!=free_list.end()) //有后一个时
{
if(start+length==(*it)->start)
link_next = true;
}
if(link_prev && link_next) //与前后都相连
{
(*last_it)->length += length + (*it)->length;
free_list.erase(it);
}
else if(link_prev) //只与前相连
{
(*last_it)->length += length;
}
else if(link_next) //只与后相连
{
(*it)->start = start;
(*it)->length += length;
}
else //前后都不相连
{
Free *fr = new Free(start,length);
free_list.insert(it,fr);
}
}
void print_free()
{
cout <<endl<<"空闲区状态:"<< endl<< endl<<"起始地址 大小" << endl;
for(list<Free *>::iterator it=free_list.begin();it!=free_list.end();it++)
{
cout<<" "<< (*it)->start << " "<< (*it)->length << endl;
}
cout <<"______________________________________" <<endl<<endl<<endl;
}
class Task:public Free //定义分配分区类
{
public:
Task()
{};
Task(int n,int s,int l):Free(s,l)
{
name = n;
}
void do_request(int name,int length);
void do_revoke(int name);
friend void print_task();
protected:
int name;
};
list<Task *> task_list; //分配可用起始地址
void Task::do_request (int name,int size)
{
if(name==0)
{
cout << "申请不合法!非法作业名!" << endl<<endl;
return;
}
if(size>Residue)
{
cout << "申请不合法!超出最大可用内存!" << endl<<endl;
return;
}
bool find = false; //查找是否已存在同名作业
list<Task *>::iterator it=task_list.begin();
while(it!=task_list.end())
{
if((*it)->name==name)
{
find=true;
break;
}
it++;
}
if(find)
{
cout << "此作业已存在!" << endl<<endl;
return;
}
int start=get_free(size); //从空闲分区选择合适的空间
if(start==-1) //未找到合适空间
{
cout << "系统内存不足!作业等待!" << endl<<endl;
return;
}
Task *ta = new Task(name,start,size);
task_list.push_back(ta);
cout << "作业申请内存成功!" <<endl<<endl;
}
void Task::do_revoke (int name)
{
if(name==0)
{
cout << "错误!不能回收系统内存!" << endl;
return;
}
bool find = false; //查找要回收的作业是否存在
list<Task *>::iterator it=task_list.begin();
while(it!=task_list.end())
{
if((*it)->name==name)
{
find=true;
break;
}
it++;
}
if(!find)
{
cout << "错误!作业名不存在!" << endl;;
return;
}
free_task((*it)->start,(*it)->length);
task_list.erase(it);
cout << "回收作业占用内存成功!" << endl;
}
void print_task()
{
cout << "_____________________________________" << endl;
cout <<"作业名称 起始地址 大小" << endl;
for(list<Task *>::iterator it=task_list.begin();it!=task_list.end();it++)
{
cout <<" "<< (*it)->name <<" "<< (*it)->start <<" "<< (*it)->length << endl;
}
cout << "_____________________________________" << endl;
}
int main()
{
cout <<"*******************************************" <<endl;
cout <<" 主存储器空间的分配和回收 "<<endl;
cout <<"*******************************************" <<endl<<endl<<endl;
Free *fr1 = new Free(fst_free,fst_size); //把系统占用后剩余的内存空间计入空闲分区表
free_list.push_back(fr1);
print_free();
bool quit=false;
while(!quit)
{
Task T;
Free F;
cout <<"a.申请内存 b.回收内存"<<endl;
cout <<"c.查看作业 0.退出程序"<<endl<<endl;
cout <<"请选择:";
char op;
cin>>op;
if(op=='a'||op=='A')
{
int name;
int size;
cout << "请输入作业名及占用空间大小:";
cin >> name;
cin >> size;
T.do_request(name,size);
print_free();
}
else if(op=='b'||op=='B')
{ int name;
cout << "请输入要回收的作业名:";
cin >> name;
T.do_revoke(name);
print_free();
}
else if(op=='c'||op=='C')
{
print_task();
}
else if(op=='0')
{
break;
}
else
{
cout << "非法操作!" << endl;
}
char con;
cout << "继续(Y/N):";
cin >> con;
if(con=='n' || con=='N')
{
quit=true;
}
system("cls");
}
}
六、打印的程序运行时初值和运行结果
七、实验小结
模拟在可变分区管理方式下采用最先适应算法实现了主存分配和回收,整个程序由两个类构成其主体,空闲区类和申请空间类。使的整个程序更结构化。程序在编写过程中也遇到了很多问题,还好在查询各方面资料后都得以解决。每一个的程序的编写成功都是一件不易的工程不仅是对能力的检测,也是对心态的检测。
文案大全
展开阅读全文