操作系统实验-动态分区管理

实验内容

(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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁拾陆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值