操作系统 动态分区存储管理
实验要求
通过编写动态分区存储管理的模拟程序,加深对操作系统存储管理功能中的动态分区管理方式、空闲分区表等相应知识的理解。
实验内容
实现动态分区存储管理方式下存储空间的分配和去配。
-
循环首次适应算法:每次都从上一次分配的空闲区继续循环遍历所有的空闲区。若再次回到上一次的位置,就代表没有可用的空闲区。
-
最坏适应算法:每次都寻找最大的空闲区进行分配,如果最大的空闲区都不够分配那么就没有可分配的空闲区。
当进程移出空闲区后需要进行空闲区的合并。将相邻的空闲区合并成一个分区。
作业流程
j0~j6调入,j2、j3调出,j5调入,j0、j1调出,j0调入,j5调出,j6调入,j0、j4、j6调出
//Partition.h
#pragma once
#include <iostream>
using namespace std;
/// <summary>
/// 空闲分区类
/// </summary>
class Partition
{
public:
double startAddress;//分区开始地址
double length;//分区长度
Partition(double startAddress, double length);
};
/// <summary>
/// 作业
/// </summary>
class Job
{
public:
int num;//作业编号
bool enter;//是否已经调入内存
double startAddress;//内存中的起始地址
double size;//大小
Job(double size, int num);
};
/// <summary>
/// 作业流程
/// </summary>
class JobFlow
{
public:
Job* job;//作业
bool enter;//标志作业是要调入内存还是调出内存
JobFlow(Job* job, bool enter);
};
//Partition.cpp
#include "Partition.h"
/// <summary>
/// 构造函数
/// </summary>
/// <param name="startAddress">空闲分区起始地址</param>
/// <param name="length">长度</param>
Partition::Partition(double startAddress, double length)
{
this->startAddress = startAddress;
this->length = length;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="size">作业大小</param>
/// <param name="num">作业编号</param>
Job::Job(double size, int num)
{
this->num = num;
this->enter = false;
this->startAddress = -1;
this->size = size;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="job">作业</param>
/// <param name="enter">该作业是要调入内存还是调出内存</param>
JobFlow::JobFlow(Job* job, bool enter)
{
this->job = job;
this->enter = enter;
}
//DynamicPartitionStorageManagement.h
#pragma once
#include <iostream>
#include <list>
#include "Partition.h"
using namespace std;
/// <summary>
/// 动态分区存储管理
/// </summary>
class DynamicPartitionStorageManagement
{
static double threshold;//阈值
static void mergePartition(list<Partition>& P, list<Partition>::iterator curitr);
static void mergeFront(list<Partition>& P, list<Partition>::iterator curitr);
static void mergeBack(list<Partition>& P, list<Partition>::iterator curitr);
public:
static void printTable(list<Partition>& P);
static void nextFit(list<Partition>& P, list<JobFlow>& J);
static void worstFit(list<Partition>& P, list<JobFlow>& J);
};
//DynamicPartitionStorageManagement.cpp
#include "DynamicPartitionStorageManagement.h"
double DynamicPartitionStorageManagement::threshold = 0.1;
/// <summary>
/// 打印空闲分区表
/// </summary>
/// <param name="P">空闲分区链表</param>
void DynamicPartitionStorageManagement::printTable(list<Partition>& P)
{
int num = 0;
cout << "----------------------------------------" << endl;
cout << "分区编号" << "\t起始地址" << "\t空间大小" << endl;
for (list<Partition>::iterator itr = P.begin(); itr != P.end(); itr++)
{
cout << num++ << "\t\t" << itr->startAddress << "\t\t" << itr->length << endl;
}
cout << "----------------------------------------" << endl;
}
/// <summary>
/// 合并前一分区
/// </summary>
/// <param name="P">空闲分区链表</param>
/// <param name="curitr">当前分区</param>
void DynamicPartitionStorageManagement::mergeFront(list<Partition>& P, list<Partition>::iterator curitr)
{
list<Partition>::iterator preitr = curitr;
preitr--;
if (curitr->startAddress - preitr->startAddress - preitr->length
< DynamicPartitionStorageManagement::threshold)//与前一块分区合并
{
curitr->length = curitr->length + curitr->startAddress - preitr->startAddress;
curitr->startAddress = preitr->startAddress;
P.erase(preitr);
}
}
/// <summary>
/// 合并后一分区
/// </summary>
/// <param name="P">空闲分区链表</param>
/// <param name="curitr">当前分区</param>
void DynamicPartitionStorageManagement::mergeBack(list<Partition>& P, list<Partition>::iterator curitr)
{
list<Partition>::iterator nextitr = curitr;
nextitr++;
if (nextitr->startAddress - curitr->startAddress - curitr->length
< DynamicPartitionStorageManagement::threshold)//与后一块分区合并
{
curitr->length = nextitr->length + nextitr->startAddress - curitr->startAddress;
P.erase(nextitr);
}
}
/// <summary>
/// 合并分区
/// </summary>
/// <param name="P">空闲分区链表</param>
/// <param name="curitr">当前分区</param>
void DynamicPartitionStorageManagement::mergePartition(list<Partition>& P, list<Partition>::iterator curitr)
{
list<Partition>::iterator lastitr = P.end();//标志最后一块分区
lastitr--;
if (curitr != P.begin() && curitr != lastitr)//当前空闲区不在首尾
{
DynamicPartitionStorageManagement::mergeFront(P, curitr);
DynamicPartitionStorageManagement::mergeBack(P, curitr);
}
else if (curitr == P.begin() && curitr != lastitr)//当前空闲区在开头且不在末尾
{
DynamicPartitionStorageManagement::mergeBack(P, curitr);
}
else if (curitr != P.begin() && curitr == lastitr)//当前空闲区在末尾且不在开头
{
DynamicPartitionStorageManagement::mergeFro