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