操作系统实验 连续内存分配 首次适应(FF)算法

1.实验要求

操作系统实验——编程实现首次适应算法。已知作业名、作业大小、作业提交时间、内存容量、碎片大小,要求使用分区大小不等的内存分区方法和首次适应分配算法给每次到来的作业分配内存。输出内存分区情况和分配情况。

2.算法描述

分区大小不等的内存分区法:
可把内存区划分成含有多个较小的分区、适量的中等分区及少量的大分区
首次适应算法(first fit):
在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止如果分区大小-作业大小<=碎片,则直接分配,否则,按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲链中。若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。

3.实验源码

#include<stdio.h>
#include<iostream>
#include<iomanip>
using namespace std;

//操作系统实验 基于顺序搜索的连续 动态分区分配算法 按地址递增 首次适应算法 

#define Free 0 		//	空闲状态
//	#define Busy 1 		//	已用状态
//	#define OK 1    	//	完成
#define ERROR 0 	//	出错
#define MAX_length 640 	//	最大内存空间为640KB
#define Begin_address 0 //  初始地址从 0 开始 
#define Size 10         //  不可分割的最小值 

typedef int Status;

typedef struct freearea		//	定义一个空闲区说明表结构
{
	int ID;
	long size;
	long address;
	int state;
}ElemType;

typedef struct DuLNode 	//	double linked list
{
	ElemType data;
	struct DuLNode *prior; 	//	前趋指针
	struct DuLNode *next;  	//	后继指针
}DuLNode, *DuLinkList;

int n;
DuLinkList block_first; 	//	头结点
DuLinkList block_last;  	//	尾结点   
//==============================================//
void alloc();         	    //	内存分配
Status free2(int); 			//	内存回收
Status free1(int); 			//	作业回收
Status First_fit(int, int);	//	首次适应算法
void show();				//	查看分配
Status Initblock();			//	开创空间表
Status Allocation(int, int);	//	传入分区名及大小

//==============创建双向链表=========================//	
Status Initblock()	//	开创带头结点的内存空间链表
{
	block_first = (DuLinkList)malloc(sizeof(DuLNode));
	block_last = (DuLinkList)malloc(sizeof(DuLNode));

	block_first->prior = NULL;
	block_first->next = block_last;
	block_first->data.state = 3;      //  便于 编程 
	block_last->prior = block_first;
	block_last->next = NULL;

	block_last->data.address = Begin_address;
	block_last->data.size = MAX_length;
	block_last->data.ID = 0;
	block_last->data.state = Free;

	return 1;
}


//============ 动态分区 ========================//

Status Allocation(int ID, int request)	//	传入分区名及大小
{
	//	为申请作业开辟新空间且初始化
	DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));

	temp->data.ID = ID;
	temp->data.size = request;
	temp->data.state = 1;

	DuLNode *p = block_first->next;
	while (p)
	{
		if (p->data.ID == ID)
		{
			p->data.size += request;
			DuLNode *r = p->next;
			while (p)
			{
				p->data.address += request;
				p = p->next;

			}
			return 1;
			break;
		}
		if (p->data.state == Free && p->data.size == request)
		{
			//	有大小恰好合适的空闲块
			p->data.state = 1;
			p->data.ID = ID;

			return 1;
			break;
		}

		if (p->data.state == Free && p->data.size > request)
		{
			//	有空闲块能满足需求且有剩余
			temp->prior = p->prior;
			temp->next = p;

			p->prior->next = temp;
			p->prior = temp;

			temp->data.address = p->data.address;  //  地址 

			p->data.address = temp->data.address + temp->data.size;
			p->data.size = p->data.size - request;

			return 1;
			break;
		}
		p = p->next;
	}
	return ERROR;
}

//==================== 首次适应算法 =======//

Status First_fit(int ID, int request)
{
	//   	cout<<ID<<" "<<request;
	DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));

	temp->data.ID = ID;
	temp->data.size = request;
	temp->data.state = 2;

	DuLNode *p = block_first->next;
	while (p)
	{
		if ((p->data.state == 1) && (p->data.size - request >= 0) && (p->data.size - request <= Size))
		{
			//	有大小恰好合适的空闲块 或所剩为碎片
			p->data.state = 2;
			p->data.ID = ID;

			return 1;
			break;
		}

		if ((p->data.state == 1) && (p->data.size - request > Size))
		{
			//	有空闲块能满足需求且有剩余
			temp->prior = p->prior;
			temp->next = p;

			p->prior->next = temp;
			p->prior = temp;

			temp->data.address = p->data.address;  //  地址  

			p->data.address = temp->data.address + temp->data.size;
			p->data.size = p->data.size - temp->data.size;

			return 1;
			break;
		}
		p = p->next;
	}
	return ERROR;
}
//====================分区 =======================//
void alloc()
{
	int ID, request;
	cout << "请输入分区号、需要分配的主存大小(单位:KB):";
	cin >> ID >> request;
	if (request < 0 || request == 0)
	{
		cout << "分配大小不合适,请重试!" << endl;
	}
	if (Allocation(ID, request) == 1)
		cout << "分配成功!" << endl;
	else
		cout << "内存不足,分配失败!" << endl;
}

//================== 主存回收  ===================//

Status free2(int ID)
{
	DuLNode *p = block_first;
	while (p)
	{
		if (p->data.ID == ID)
		{
			if (p->data.state == 0)
				cout << "\n区间:" << ID << " 已回收!\n";
			else
				cout << "\n分区:" << ID << " 回收成功!" << endl;

			p->data.state = 0;

			//	  与前面的空闲块相连
			if (p->prior->data.state == 0)
			{
				p->prior->data.size += p->data.size;

				p->prior->next = p->next;
				p->next->prior = p->prior;

				p = p->prior;   //  指针 前移 
			}

			//	  与后面的空闲块相连
			if (p->next->data.state == 0)
			{
				p->data.size += p->next->data.size;

				if (p->next->next == NULL) { p->next = NULL; }
				else
				{
					p->next->next->prior = p;
					p->next = p->next->next;
				}
			}
			break;
		}
		p = p->next;
	}
	return 1;
}

//=========== 撤销作业  ===================//

Status free1(int ID)
{
	int i = 1;
	DuLNode *p = block_first;
	while (p)
	{
		if (p->data.ID == ID)
		{
			if (p->data.state == 2)
				cout << "\n作业:" << ID << " 撤销成功!" << endl;
			if (p->data.state == 1)
				cout << "\n作业:" << ID << " 已撤销!" << endl;
			if (p->data.state == 0)
				cout << "\n区间:" << ID << " 未分配!" << endl;

			p->data.state = 1;

			//	  与前面的空闲块相连
			if (p->prior->data.state == 1)
			{
				p->prior->data.size += p->data.size;

				p->prior->next = p->next;
				p->next->prior = p->prior;

				p = p->prior;   //  指针 前移 
			}

			//	  与后面的空闲块相连
			if (p->next->data.state == 1)
			{
				p->data.size += p->next->data.size;

				if (p->next->next == NULL) { p->next = NULL; }
				else
				{
					p->next->next->prior = p;
					p->next = p->next->next;
				}
			}
			break;
		}
		p = p->next;
	}
	return 1;
}

//====================  显示主存分配情况  ====//

void show()
{
	//		cout<<"主存分配情况 :       \n";	

	DuLNode *p = block_first->next;
	printf("\n\n分区(作业)号    起始地址      所占内存大小(KB)          状态\n\n");

	while (p)
	{
		if (p->data.ID == Free)
			cout << "Free";
		else
			printf("%4d", p->data.ID);

		printf("%17d", p->data.address);
		printf("%18d", p->data.size);

		if (p->data.state == Free)
			cout << setw(22) << "空闲\n";
		else if (p->data.state == 1)
			cout << setw(24) << "已分区\n";
		else
			cout << setw(26) << "已分配作业\n";

		p = p->next;
	}
	cout << "\n=====================================================";
}


int main() 
{
	Initblock();
	int choice;
	int i;
	cout << endl;

	cout << "  ++++++++++++++++++++++++++\n";
	cout << "  ++++++++++++++ 动态分区分配方式的模拟+++\n";
	cout << "  +++++++首次适应算法++++++++++++++++++++++++\n";
	for (i = 0; ; i++)
	{
		show();

		cout << "\n\n  1: 分配内存\n";
		cout << "  2: 装入作业\n";
		cout << "  3: 撤销作业\n";
		cout << "  4: 回收内存\n";
		cout << "  0: 退出\n\n";
		cout << "请输入您的操作: ";
		cin >> choice;

		if (choice == 1)	// 分配内存
			alloc();
		else if (choice == 2)
		{
			int a, b;
			cout << "请输入作业号、大小: ";
			cin >> a >> b;

			if (First_fit(a, b) == 0)
			{
				cout << "\n装不下!没有足够大的区间\n";
			}
		}
		else if (choice == 3)	// 撤销作业
		{
			int ID;
			cout << "请输入您要撤销的作业号:";
			cin >> ID;
			free1(ID);
		}
		else if (choice == 4)	// 内存回收
		{
			int ID;
			cout << "请输入您要释放的分区号:";
			cin >> ID;
			free2(ID);
		}
		else if (choice == 0)	//	退出
			break;
		else 	
		{
			cout << "输入有误,请重试!" << endl;
			continue;
		}
	}

	return 0;
}


  • 9
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值