操作系统--可变分区分配

一、实验目的

动态分区分配是根据进程的实际需要,动态地为之分配内存空间,而在分配时,须按照一定的分配算法,从空闲分区表或空闲分区链中选出一分区分配给该作业。

二、实验环境

VS2017+PC

三、实验内容

在本实验中运用了四种分配算法,分别是1.首次适应算法,⒉循环首次适应算法,3.最坏适应算法4.最佳适应算法。

四、实验步骤

1.首次适应算法:在该算法中.把主存中所有空闲区按其起始地址递增的次序排列。在为作业分配存储空间时.从上次找到的空闲分区的下一个空闲分区开始查找.直到找到第一个能满足要求的空闲区.从中划出与请求的大小相等的存储空间分配给作业.余下的空闲区仍留在空闲区链中。

2.循环首次适应算法:该算法是由首次适应算法演变而成,在为进程分配内存空间时,不再是每次都从第一个空间开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业,为实现本算法,设置一个全局变量f,来控制循环查找,当f%N==O时,f=0;若查找结束都不能找到一个满足要求的分区,则此次内存分配失败。

3.最佳适应算法:在该算法中.把主存中所有空闲区按其起始地址递增的次序排列。在为作业分配存储空间时.从上次找到的空闲分区的下一个空闲分区开始查找.直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都小.从中划出与请求的大小相等的存储空间分配给作业.余下的空闲区仍留在空闲区链中

4.最坏适应算法:在该算法中.把主存中所有空闲区按其起始地址递增的次序排列。在为作业分配存储空间时.从上次找到的空闲分区的下一个空闲分区开始查找.直到找到一个能满足要求的空闲区且该空闲区的大小比其他满足要求的空闲区都大.从中划出与请求的大小相等的存储空间分配给作业.余下的空闲区仍留在空闲区链中。

五、总结

在这次实验中更加清晰的知道:分区的个数和大小不是固定不变的,而是可变的,随装入的作业动态划分,主存的分配和回收的实现与主存储器的管理方式有关,通过做这次实验帮助我理解了可变分区管理方式下应怎样实现贮存空间的分配与回收。由于本次实验是模拟主存的分配,所以主存分配区给作业后并不实际启动装入程序装入作业,采用输入的方式。

六、代码

// Test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;
const int MaxNumber = 100;
int FreePartition[MaxNumber];//空闲可用分区
int Partition[MaxNumber];//进程所需分区
int  PartitionNum, ProcessNum;
int n; //空闲分区个数
int m;//需要分配的进程个数

void FF() //首次适应算法
{
	//寻找大小能满足进程要求的分区
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (Partition[i] <= FreePartition[j]) {
				FreePartition[j] = 0;
				cout << "第 " << i + 1 << "个进程被分配给了分区 " << j << endl; break;
			}
			if (j == n - 1) {
				cout << "系统没有足够大的内存分配给进程 " << i << " ,内存分配失败!" << endl;
			}
		}
	}
}

void NF() //循环首次适应算法
{
	int lastUsed = 0;
	int count = 0;
	bool check[100];
	while (count < m) {
		if (lastUsed == n) {
			lastUsed -= n;
		}
		for (int i = lastUsed; i < (n + lastUsed); i++) {
			if (i < n) {
				if (FreePartition[i] >= Partition[count]) {
					FreePartition[i] = 0;
					cout << "空闲分区" << i << "分配了" << Partition[count] << "给进程" << count << endl;
					lastUsed = i + 1;
					break;
				}
			}
			else {
				if (FreePartition[i - n] >= Partition[count]) {
					FreePartition[i - n] = 0;
					cout << "空闲分区" << i - n << "分配了" << Partition[count] << "给进程" << count << endl;
					lastUsed = i + 1; break;
				}
			}
			//没有足够大的进程
			if (i == n + lastUsed - 1) {
				cout << "系统没有足够大的内存分配给进程" << count << ",内存分配失败!" << endl;
			}
		}
		count++;
	}
}

void BF() //最佳适应算法
{
	int count = 0;
	int *Number = new int[n];//记录每个分区内存和进程的内存差
	//让内存最小的进程先判断
	int *Temp = new int[m];
	for (int i = 0; i < m; i++)
	{
		Temp[i] = Partition[i];
	}
	int *number = new int[m];
	for (int i = 0; i < m; i++)
	{
		number[i] = i;
	}
	for (int i = 0; i < m; i++)
	{
		for (int j = i + 1; j < m; j++)
		{
			if (Temp[i] > Temp[j]) {
				int num = 0;
				num = Temp[i];
				Temp[i] = Temp[j];
				Temp[j] = num;

				num = number[i];
				number[i] = number[j];
				number[j] = num;
			}
		}
	}

	while (count < m) {
		//为进程分配内存
		for (int i = 0; i < n; i++) {
			Number[i] = (FreePartition[i] - Partition[number[count]]) >= 0 ? (FreePartition[i] - Partition[number[count]]) : 10000;//如果分区内存大于进程所需,设为10000表示无效分区
		}
		int a = 0;//记录最合适分区的位置
		for (int i = 1; i < n; i++)
		{
			//只需要求数组第一个,即相差最小的
			if (Number[i] < Number[0]) {
				int num = 0;
				a = i;
				num = Number[i];
				Number[i] = Number[0];
				Number[0] = num;
			}

		}
		if (FreePartition[a] >= Partition[number[count]]) {
			FreePartition[a] = 0;
			cout << "分区" << a << "分配给了进程" << number[count] << endl;
		}
		else {
			cout << "系统没有足够大的内存分配给进程 " << number[count] << " ,内存分配失败!" << endl;
		}
		count++;
	}
}

void WF() //最坏适应算法
{
	int count = 0;
	int *Number = new int[n];//记录每个分区内存和进程的内存差
	//让内存最大的进程先判断
	int *Temp = new int[m];
	for (int i = 0; i < m; i++)
	{
		Temp[i] = Partition[i];
	}
	int *number = new int[m];
	for (int i = 0; i < m; i++)
	{
		number[i] = i;
	}
	for (int i = 0; i < m; i++)
	{
		for (int j = i + 1; j < m; j++)
		{
			if (Temp[i] < Temp[j]) {
				int num = 0;
				num = Temp[i];
				Temp[i] = Temp[j];
				Temp[j] = num;

				num = number[i];
				number[i] = number[j];
				number[j] = num;
			}
		}
	}

	while (count < m) {
		//为进程分配内存
		for (int i = 0; i < n; i++) {
			Number[i] = (FreePartition[i] - Partition[number[count]]) >= 0 ? (FreePartition[i] - Partition[number[count]]) : -1;//如果分区内存小于进程所需,设为-1表示无效分区
		}
		int a = 0;//记录最合适分区的位置
		for (int i = 1; i < n; i++)
		{
			//只需要求数组第一个,即相差最大的
			if (Number[i] > Number[0]) {
				int num = 0;
				a = i;
				num = Number[i];
				Number[i] = Number[0];
				Number[0] = num;
			}

		}

		if (FreePartition[a] >= Partition[number[count]]) {
			FreePartition[a] = 0;
			cout << "分区" << a << "分配给了进程" << number[count] << endl;
		}
		else {
			cout << "系统没有足够大的内存分配给进程 " << number[count] << " ,内存分配失败!" << endl;
		}
		count++;
	}
}

int main()
{
	cout << "请输入空闲分区个数:" << endl;
	cin >> n;
	cout << "请输入空闲分区大小:" << endl;
	for (int i = 0; i < n; i++) {
		cin >> FreePartition[i];
	}
	cout << "请输入进程个数:" << endl;
	cin >> m;
	cout << "请输入进程所需分区大小:" << endl;
	for (int i = 0; i < m; i++) {
		cin >> Partition[i];
	}
	int choice;
	while (1)
	{
		cout << "-----------请输入实现的分配方式-----------" << endl;
		cout << "-----------1.首次适应算法-----------------" << endl;
		cout << "-----------2.循环首次适应算法-------------" << endl;
		cout << "-----------3.最佳适应算法-----------------" << endl;
		cout << "-----------4.最坏适应算法-----------------" << endl;
		cout << "-----------5.退出-------------------------" << endl;
		cin >> choice;
		if (choice > 5)
			break;
		switch (choice)
		{
		case 1:
			FF();
			break;
		case 2:
			NF();
			break;
		case 3:
			BF();
			break;
		case 4:
			WF();
			break;
		case 5:
			exit(0);
		}

	}
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可变分区分配是一种存储管理技术,用于为进程分配内存空间。它的主要特点是分区大小不固定,可以根据进程的需要进行动态调整。在这种技术中,物理内存被划分为多个可变大小的分区,每个分区可以分配给一个进程使用。 下面是实验四的步骤: 1. 设计数据结构:设计数据结构来存储可用分区和已分配分区的信息,包括分区的起始地址、大小和状态等。 2. 初始化分区:将整个物理内存划分为一个或多个可用分区,并将其添加到可用分区列表中。 3. 进程申请内存:当进程需要内存时,它向操作系统发出请求。操作系统会在可用分区列表中查找一个大小足够的分区来满足进程的需要。 4. 分配分区:如果找到了一个合适的分区操作系统会将该分区标记为已分配,并从可用分区列表中删除该分区,然后将该分区的起始地址返回给进程。 5. 释放分区:当进程不再需要某个分区时,它将释放该分区操作系统将该分区标记为可用,并将其添加到可用分区列表中。 6. 内存回收:当所有进程都结束时,操作系统将所有已分配分区标记为可用,以便下一批进程使用。 7. 碎片整理:在分配和释放分区的过程中,可能会出现内存碎片。为了最大化可用内存空间,可以实现碎片整理算法,将多个相邻的可用分区合并成一个更大的分区。 这些步骤可以通过编程实现。在实现过程中,需要注意保证数据结构的完整性和正确性,以及在内存分配和释放过程中避免死锁等问题的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值