操作系统实验-动态分区管理
实验内容
(1)动态分区管理的主存分配模拟系统的设计—最先适应法、最佳适应法、最坏适应法(选择1~3种),模拟实现内存的分配回收;
(2)能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等;
(3)能够选择分配或回收操作;并能显示完成内存分配或回收后内存空间的使用情况;
(4)能够显示进程在内存的存储地址、大小等
实验代码
1,c++
2,ConsoleApplication1.cpp 主函数在此文件中。用于选择操作。
3,service.cpp 数据服务层,当然为了偷懒,一些用户交互操作也放在了这一层(如添加进程,,,)
4,DataStruct.h 其中定义了数据结构。
5, partition.cpp 一个用于内存管理的类,其中包括对分区的查找,整理,,,
6,processM.cpp 一个用于进程管理可有可无的类。
ConsoleApplication1.cpp文件
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include"service.h"
using namespace std;
int main()
{
//初始化内存
InitParS();
while (1) {
cout << "*******************************菜 单********************************" << endl;
cout << "----1、显示分区状态 " << "----2、释放分区 " << "----3、分配分区" << endl;
cout << "----4、添加进程 " << "----5、显示当前请求进程 " << "----6、显示可用表" << endl;
cout << " 请输入要执行的菜单选项:";
int choice;
cin >> choice;
switch (choice) {
case 1:
PriRAMS();
break;
case 2:
ReleaseParS();
break;
case 3:
ChooseDisWay();
break;
case 4:
AddProS();
break;
case 5:
PriRequestProS();
break;
case 6:
PriFreeRAMS();
default:
break;
}
}
}
DataStruct.h 文件
#pragma once
#include<string>
using namespace std;
/*
* 数据结构定义文件
*/
//分区表
struct RAM
{
int partnum;//区号
int start; //起始地址
int end; //结束地址
int length;//分区长度
int status; //分区状态 1表示已使用 0表示未使用
string processName;//如果该分区有进程,则表示该分区的进程名称
RAM* next;
};
//可用表
struct FREERAM
{
int freePartNo = -1; //空闲区号
int freeLength = -1; //空闲区长度
int freeStart = -1; //空闲区起址
};
//进程表
struct PROCESS
{
string proname;//进程的名称
int proram; //进程所需要的内存空间大小
int statue; //进程的状态 1表示已经分配,0表示未分配
};
service.cpp文件
#include "service.h"
#include<iostream>
#include"DataStruct.h"
#include"partition.h"
#include"processM.h"
using namespace std;
//数据层对象
partition PAR;//内存管理
processM PRO; //进程管理
/*
* 打印分区表
*/
void PriRAMS()
{
cout << endl;
PAR.PrintRAM();
}
/*
* 打印可用表
*/
void PriFreeRAMS()
{
cout << endl;
PAR.PrintFreeRAM();
}
/*
* 打印进程请求表
*/
void PriRequestProS()
{
cout << endl;
PRO.PrintRequest();
}
/*
* 初始化内存
*/
void InitParS()
{
int totalRAM = 0;
cout << "请输入内存总大小:";
cin >> totalRAM;
PAR.InitRam(totalRAM);
cout << "初始化内存完成" << endl;
cout << endl;
}
/*
* 向请求表中添加进程
*/
void AddProS()
{
int num=0;
cout << endl;
cout << "----------------------添加进程-----------------------" << endl;
cout << "输出要添加的进程个数:";
cin >> num;
for (int i = 0; i < num ; i++)
{
PROCESS pro;
cout << i << ":" << endl;
cout << "进程的名称:";
cin >> pro.proname;
cout << "进程占用内存的大小:";
cin >> pro.proram;
pro.statue = 0;
PRO.AddProcess(pro);
cout << endl;
}
}
/*
* 根据方式获取区号
* way:使用的方法 0:最先适应法; 1:最佳适应法; 2:最坏适应法
* len: 进程长度
* return:区号 (-1:无可用区)
*/
int GetPartnum(int way, int len)
{
//判断是否存在可用表
if (0==PAR.freeNum)
{
return -1;
}
if (0==way)
{
//最先适应法根据首地址,不需要排序,所以直接查询即可
return PAR.SerarchFreeRam(len);
}
else if (1==way)
{
//最佳适应法,需要先将可用表按照递增排序
PAR.AscendingOrder();
return PAR.SerarchFreeRam(len);
}
else
{
//最坏适应法,需要将可用表按照递减排序
PAR.DecreasingOrder();
//最坏适应算法,只需要取最大的一个分区进行判断即可
if (len < PAR.FreeRam[0].freeLength)
{
return PAR.FreeRam[0].freePartNo;
}
}
return -1;
}
/*
* 分配进程
* way:使用的方法 0:最先适应法; 1:最佳适应法; 2:最坏适应法
*/
void DistributeProS(int way)
{
//因为最先适应算法不需要排序,所以可以直接从可用表中进行查找
for (int i = 0; i < PRO.ProcessNum; i++)
{
int len = PRO.ProRequest[i].proram;
//根据分配方式获取可用区的区号
int partno = GetPartnum(way, len);
if (-1 != partno)//表示现有可用表,可用为该进程分配空间
{
bool result = PAR.DistributeProcess(partno, PRO.ProRequest[i]);
if (true == result)
{
//分配成功后,将该进程标为已分配
PRO.ProRequest[i].statue = 1;
}
}
}
//更新进程请求表
PRO.UpadateRequest();
}
/*
* 让用户选择分配的方法
*/
void ChooseDisWay()
{
cout << endl;
int way = 0;
cout << "------------------分配方法---------------------" << endl;
cout << "---0:最先适应法---1:最佳适应法---2:最坏适应法---" << endl;
cout << "输入分配的方法:";
cin >> way;
DistributeProS(way);
}
/*
* 让用户选择要释放的分区
*/
void ReleaseParS()
{
cout << endl;
int partno=-1;
cout << "------------------释放分区------------------" << endl;
cout << "输入要释放分区的区号";
cin >> partno;
PAR.ReleasePartition(partno);
}
partition.cpp 文件
/***************************************
类的成员变量
int totalRAM = 0; //给定的内存
int partitionNum = 0; //分区个数
int freeNum = 0;//空闲分区个数
RAM* ToalRam=NULL;//分区表
FREERAM FreeRam[100]; //空闲(可用)区表
*********/
#include "partition.h"
using namespace std;
/*
* 初始化内存
* totalRAM: 内存大小
*/
void partition::InitRam(int totalRAM)
{
this->totalRAM = totalRAM;
ToalRam = new RAM;
ToalRam->partnum = 0;
ToalRam->start = 0;
ToalRam->length = totalRAM;
ToalRam->end = totalRAM - 1;
ToalRam->next = NULL;
ToalRam->status = 0;
//更新可用表
UpadteFreeRam();
}
/*
* 初始化分区的区号
*/
void partition::InitpartNo()
{
RAM* p = ToalRam;
int i = 0;
for ( ; p!=NULL ; p=p->next)
{
p->partnum = i;
i++;
}
partitionNum = i;
}
/*
* 更新空闲分区,每次改变分区表的时候,都需要更新空闲分区
*/
void partition::UpadteFreeRam()
{
//初始化区号
InitpartNo();
//初始化空闲表
for (int i = 0; i <= freeNum; i++) {
FreeRam[i].freeLength = -1;
FreeRam[i].freePartNo = -1;
FreeRam[i].freeStart = -1;
}
freeNum = 0;
//找出所有空闲区
for (RAM* p=ToalRam;p!=NULL;p=p->next)
{
if (p->status==0)
{
FreeRam[freeNum].freeLength = p->length;
FreeRam[freeNum].freeStart = p->start;
FreeRam[freeNum].freePartNo = p->partnum;
freeNum++;
}
}
}
/*
* 从可用表中查询第一个符合条件的分区
* len: 可用区的长度大于len
*/
int partition::SerarchFreeRam(int len)
{
for (int i = 0; i < freeNum; i++)
{
if (FreeRam[i].freeLength >= len)
{
return FreeRam[i].freePartNo;
}
}
return -1;
}
/*
* 向指定的分区中,分配进程
* partno:分区区号
* pro: 需要分配的进程
* return: true 分配成功 ,false 分配失败
*/
bool partition::DistributeProcess(int partno, PROCESS pro)
{
for (RAM* p = ToalRam; p != NULL; p = p->next)
{
if (p->partnum==partno)
{
//如果该分区的长度等于进程所需长度,则直接将该分区分配给该进程即可
if (p->length == pro.proram)
{
//更新分区
p->status = 1;
p->processName = pro.proname;
//更新可用表
UpadteFreeRam();
return true;
}
else
{
//否则,该分区的长度大于该进程所需长度
//将该分区的一部分分给该进程,剩下的部分作为一个新的分区
//为新分区初始化
RAM *nram = new RAM;
nram->next = NULL;
nram->partnum = 0; //初始化编号,将会在更新可用表中统一编号
nram->start = p->start + pro.proram;
nram->end = p->end;
nram->length = p->length - pro.proram;
nram->status = 0;
nram->next = p->next;
//将原分区的一部分分配给进程
p->status = 1;
p->processName = pro.proname;
p->length = pro.proram;
p->end = p->start + pro.proram - 1;
p->next = nram;
//更新可用表
UpadteFreeRam();
return true;
}
}
}
return false;
}
/*
* 将可用表进行递减排序
*/
void partition::AscendingOrder()
{
UpadteFreeRam();
for (int i = 0; i < freeNum - 1; i++) {
for (int j = 0; j < freeNum - i - 1; j++) {
if (FreeRam[j].freeLength > FreeRam[j + 1].freeLength) {
change(FreeRam[j].freePartNo, FreeRam[j + 1].freePartNo);
change(FreeRam[j].freeStart, FreeRam[j + 1].freeStart);
change(FreeRam[j].freeLength, FreeRam[j + 1].freeLength);
}
}
}
}
/*
* 将可用表进行递减排序
*/
void partition::DecreasingOrder()
{
UpadteFreeRam();
for (int i = 0; i < freeNum - 1; i++) {
for (int j = 0; j < freeNum - i - 1; j++) {
if (FreeRam[j].freeLength < FreeRam[j + 1].freeLength) {
change(FreeRam[j].freePartNo, FreeRam[j + 1].freePartNo);
change(FreeRam[j].freeStart, FreeRam[j + 1].freeStart);
change(FreeRam[j].freeLength, FreeRam[j + 1].freeLength);
}
}
}
}
/*
* 释放指定分区
* partno:要释放的分区的区号
*/
void partition::ReleasePartition(int partno)
{
for (RAM* p = ToalRam; p != NULL; p = p->next)
{
if (p->partnum == partno)
{
p->status = 0;
p->processName ="";
break;
}
}
//处理回收区与空闲区邻接
NeatenDebris();
}
/*
* 整理内存
* 当释放分区后,调用该函数用于处理空闲区与回收取邻接的情况*/
void partition::NeatenDebris()
{
for (RAM* p = ToalRam; p != NULL; )
{
if (p->status == 0 && p->next != NULL) {
if (p->next->status == 0) {
p->end = p->next->end;
p->length = p->length + p->next->length;
RAM* q = p->next;
p->next = q->next;
delete q;
}
else {
p = p->next;
}
}
else {
p = p->next;
}
}
//跟新可用区
UpadteFreeRam();
}
/*
* 打印分区表
*/
void partition::PrintRAM()
{
cout << "-------------------分区表---------------------" << endl;
cout << "区号\t首址\t尾址\t长度\t状态\t占用进程编号" << endl;
int i = 0;
for (RAM* p = ToalRam; p != NULL;p=p->next) {
cout << " " << p->partnum << "\t" << p->start << "\t" << p->end << "\t" << p->length << "\t";
if (p->status == 1)
cout << "占用\t" << p->processName << endl;
else
cout << "空闲" << endl;
i++;
}
cout << endl;
}
/*
* 打印可用表
*/
void partition::PrintFreeRAM()
{
cout << "-------------------------可用表信息-----------------------" << endl;
cout << "区号\t分区长度\t首地址" << endl;
for (int i = 0; i < freeNum; i++)
{
cout << FreeRam[i].freePartNo << "\t" << FreeRam[i].freeLength << "\t" << FreeRam[i].freeStart << endl;
}
}
/*
* 交换a与b的值,
*用于可用表排序的工具函数
*/
void partition::change(int& a, int& b)
{
int temp;
temp = a;
a = b;
b = temp;
}
processM.cpp文件
/****************************
类的成员变量:
PROCESS ProRequest[100]; //进程请求表
int ProcessNum = 0;//请求表中进程个数
**********************************/
#include "processM.h"
#include<iostream>
using namespace std;
/*
* 添加进程到进程请求表中
*/
void processM::AddProcess(PROCESS pro)
{
ProRequest[ProcessNum] = pro;
ProcessNum++;
}
/*
* 打印请求表
*/
void processM::PrintRequest()
{
cout << "---------------------进程请求表----------------------" << endl;
cout << "进程名称\t进程大小" << endl;
for (int i = 0; i < ProcessNum; i++) {
cout << ProRequest[i].proname << "\t\t" << ProRequest[i].proram << endl;
}
}
/*
* 更新进程请求表
*/
void processM::UpadateRequest()
{
int k = 0;
for (int i = 0; i < ProcessNum; i++)
{
if (ProRequest[i].statue!=1)
{
ProRequest[k].proname = ProRequest[i].proname;
ProRequest[k].proram = ProRequest[i].proram;
ProRequest[k].statue = ProRequest[i].statue;
k++;
}
}
ProcessNum = k;
}
本文作者:发呆鱼
本文链接:https://www.cnblogs.com/dyiblog/articles/15929774.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步