重庆分公司,新征程启航

为企业提供网站建设、域名注册、服务器等服务

操作系统实验——主存分配与释放(C语言)-创新互联

目录

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站建设、做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的柳江网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

实验要求

代码实现

运行结果

代码解析


实验要求

1、模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。

2、采用最先适应法。

3、当一个新作业要求装入主存时,必须查空闲区表,从中找出一个足够大的空闲区。若找到的空闲区大于作业需要量,这是应把它分成二部分,一部分为占用区,加一部分又成为一个空闲区。

4、当一个作业撤离时,归还的区域如果与其他空闲区相邻,则应合并成一个较大的空闲区,登在空闲区表中。

5、运行所设计的程序,输出有关数据结构表项的变化和内存的当前状态。 

代码实现
#include#define CAP 1024    //初始化内存容量 
#define SYSCAP 100  //系统所占地址,从低位开始 
#define N 1000		//进程大个数 

//作业分区 
struct USED{
	int id,sp,ep,longsize;
}a[N];

//空闲分区 
struct FREE{
	int id,sp,ep,longsize;
}b[N];

//anum为作业分区块数,bnum为空闲分区块数。初始时作业分区0块,空闲分区有1块
int anum=0,bnum=1;        
void Init()              //初始化函数,程序开始时只有一个空闲分区 
{
	b[0].id=0;b[0].sp=SYSCAP;b[0].ep=CAP;b[0].longsize=b[0].ep-b[0].sp;
	printf("\n\n--------------最先适应算法--------------\n"); 
	printf("\n内存总量为:%dk\n",CAP); 
	printf("系统占用容量为:%dk\n",SYSCAP);
	printf("---------------------------------------------\n"); 
	printf("空闲分区    起始地址    结束地址    长度\n");
	printf("   %d          %d         %d       %d\n",b[0].id,b[0].sp,b[0].ep,b[0].longsize);
	printf("---------------------------------------------\n"); 
}
void Print(int anum,int bnum)      //格式化输出作业分区和空闲分区表 
{
	int i,j;
	printf("-----------------作业分区表---------------------\n"); 
	printf("作业分区    起始地址    结束地址    长度\n");
	for(i=0;i=size)     //找到第一个能放下进程的空闲分区 
		{
			a[anum].id=anum;			//空闲区id 
			a[anum].sp=b[i].sp;			//作业内存起始地址等于空闲分区起始地址 
			a[anum].ep=a[anum].sp+size; //作业的结束地址等于起始地址+作业长度 
			b[i].sp=b[i].sp+size;		//空闲分区起始地址应向后移动size 
			a[anum].longsize=size;		//更新作业地址长度到结构体数组中 
			b[i].longsize=b[i].ep-b[i].sp;//更新空闲分区地址长度 
			anum++;						//作业数+1 
			break;						//一次只放入一个作业,结束查找 
		}
	}
	Print(anum,bnum);                   //打印结果 
}

void Merge()	//合并空闲分区,查找结束地址和开始地址重合的地址进行合并 
{
	int i,j;
	if(bnum>=1)   //当空闲分区大于等于两个时,才需要检查是否存在可合并的区间 
	{
		for(i=0;i运行结果

代码解析

将内存总量,系统内存进行宏定义(有需要的直接修改宏定义的数据即可)

定义两个结构体数组,分别用于存放和空闲分区的状态数据

anum和bnum为全局变量,分别代表作业分区和空闲分区的数量 

#include#define CAP 1024    //初始化内存容量 
#define SYSCAP 100  //系统所占地址,从低位开始 
#define N 1000		//进程大个数 
//作业分区 
struct USED{
	int id,sp,ep,longsize;
}a[N];
//空闲分区 
struct FREE{
	int id,sp,ep,longsize;
}b[N];
int anum=0,bnum=1;

初始化函数,在算法程序未开始处理前打印初始数据。这里数组下标从0开始

void Init()              //初始化函数,程序开始时只有一个空闲分区 
{
	b[0].id=0;b[0].sp=SYSCAP;b[0].ep=CAP;b[0].longsize=b[0].ep-b[0].sp;
	printf("\n\n--------------最先适应算法--------------\n"); 
	printf("\n内存总量为:%dk\n",CAP); 
	printf("系统占用容量为:%dk\n",SYSCAP);
	printf("---------------------------------------------\n"); 
	printf("空闲分区    起始地址    结束地址    长度\n");
	printf("   %d          %d         %d       %d\n",b[0].id,b[0].sp,b[0].ep,b[0].longsize);
	printf("---------------------------------------------\n"); 
}

打印结果,按顺序打印对应的结构体数据

void Print(int anum,int bnum)      //格式化输出作业分区和空闲分区表 
{
	int i,j;
	printf("-----------------作业分区表---------------------\n"); 
	printf("作业分区    起始地址    结束地址    长度\n");
	for(i=0;i

核心算法:将作业装入内存(具体实现方法全都写入注释里了,如果还有有不懂的可以私信我)

void Put()                   //进程装入作业 
{
	int size;
	printf("请输入作业%d的大小\n",anum);
	scanf("%d",&size);
	int i;
	for(i=0;i=size)     //找到第一个能放下进程的空闲分区 
		{
			a[anum].id=anum;			//空闲区id 
			a[anum].sp=b[i].sp;			//作业内存起始地址等于空闲分区起始地址 
			a[anum].ep=a[anum].sp+size; //作业的结束地址等于起始地址+作业长度 
			b[i].sp=b[i].sp+size;		//空闲分区起始地址应向后移动size 
			a[anum].longsize=size;		//更新作业地址长度到结构体数组中 
			b[i].longsize=b[i].ep-b[i].sp;//更新空闲分区地址长度 
			anum++;						//作业数+1 
			break;						//一次只放入一个作业,结束查找 
		}
	}
	Print(anum,bnum);                   //打印结果 
}

核心算法:将作业回收,作业所占据的内存重新收回变为空闲区

这里说一下代码中写的回收作业时为什么要分两种情况

情况1:

在作业回收时,进入空闲分区能直接和空闲分区直接合并,不需要增加新的空闲分区块(如下图)

回收合并后:

情况2:

在作业回收时,进入空闲分区时不能直接和空闲分区直接合并,需要增加新的空闲分区块(如下图,黄色块为待回收的作业分区)

回收合并后:

void Remove()//回收作业 
{
	int i,j,flag=1;//flag是标志位 
	printf("请输入需要回收的作业:\n");
	scanf("%d",&i);
	//回收作业存在下面两种情况 
	
	for(j=0;j

排序算法,每次进行回收后按地址从大到小进行重新排序(这一步处理必须有)

作业回收时是任意的,如果先回收了高地址块不排序,在下一次检索空闲分区时会先把高地址分出去,显然这是不符合最佳适应算法的定义的

void Sort(int anum,int bnum)//简单排序函数,将空闲区间按起始地址递增的顺序排序 
{
	int i,j,min;
	for(i=0;i

合并函数,进行检查再合并处理,这里其实是在处理前面两种情况之后出现的第三种情况

回收合并后: 

void Merge()	//合并空闲分区,查找结束地址和开始地址重合的地址进行合并 
{
	int i,j;
	if(bnum>=1)   //当空闲分区大于等于两个时,才需要检查是否存在可合并的区间 
	{
		for(i=0;i

主函数。通过用户输入来调用对应处理函数

int main()
{
	int input;//input 代表程序运行状态
	Init();//初始化,输出 
	while(1)//写一个死循环 
	{
		printf("装入作业:1  回收作业:0  其他输入结束程序\n");
		scanf("%d",&input);
		if(input==1)
		{
			Put();
		}else if(input==0)
		{
			Remove();
		}else break;//任意数字退出循环,程序结束 
	}
	return 0;
}

感谢阅读~各位有什么好的建议评论或者私信我都可以~有没看懂的地方也可以私信我~

觉得有用的话点个赞再走吧~

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


新闻名称:操作系统实验——主存分配与释放(C语言)-创新互联
本文来源:http://cqcxhl.cn/article/ddjgej.html