操作系统实验 连续内存分配 首次适应(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;elsecout << "内存不足,分配失败!" << 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";elsecout << "\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";elseprintf("%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";elsecout << 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;
}
操作系统实验 连续内存分配 首次适应(FF)算法相关推荐
- 【操作系统】连续内存分配策略
最为简单的内存分配方法之一就是将内存分为多个固定大小的分区.每个分区只能容纳一个进程. 为此,操作系统有一个表用于记录哪些内存可用和哪些内存已用. 一开始,所有内存都可用于用户进程,因此能够作为一个大 ...
- 连续内存分配与非连续内存分配
连续内存分配 首次适配:空闲分区以地址递增的次序链接.分配内存时顺序查找,找到大小能满足要求的第一个空闲分区. 最优适配:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区. 最坏适配:空闲 ...
- 【操作系统/OS笔记05】非连续内存分配:分段、分页、页表
本次笔记内容: 4.1 非连续内存分配:分段 4.2 非连续内存分配:分页 4.3 非连续内存分配:页表 文章目录 为什么需要非连续内存分配 非连续分配的优劣 分段(segment) 分段寻址方案 分 ...
- 【操作系统/OS笔记04】内存分层体系、地址生成、连续内存分配概论
本次笔记内容: 3.1 计算机体系结构及内存分层体系 3.2 地址空间和地址生成 3.3 连续内存分配:内存碎片与分区的动态分配 3.4 连续内存分配:压缩式与交换式碎片整理 文章目录 物理内存 计算 ...
- 【清华大学】操作系统 陈渝 Part3 ——物理内存管理 之 连续内存分配
[清华大学]操作系统 陈渝 Part3 --物理内存管理 之 连续内存分配 3.1计算机体系结构及内存分层 计算机体系机构 内存体系层次 管理内存方法 3.2地址空间 & 地址生成 地址空间定 ...
- 清华大学《操作系统》(六):非连续内存分配 段式、页式、段页式存储管理
背景 连续内存分配给内存分配带来了很多不便,可能所有空闲片区大小都无法满足需求大小,这个分配就会失败.基于这种现状,就有了非连续内存分配的需求.非连续分配成功的几率更高,但也面对更多的问题,比如分配时 ...
- 《操作系统》OS学习(五):连续内存分配 内存碎片、动态分配、碎片整理、伙伴系统
内存碎片 在没有其他方式辅助的情况下,我们分配给一个进程的内存是连续的.在分配时候我们需要有动态分配与碎片处理.如何理解呢?就是每个进程需要一块内存,我们要选取合适的位置的内存分配给它.当有的进程先结 ...
- 操作系统 非连续分配_操作系统中的连续和非连续内存分配
操作系统 非连续分配 In this article, we will learn about the different types of memory management techniques ...
- 操作系统-- 连续内存分配、非连续内存分配
文章目录 一.连续内存分配 1.内存碎片的问题 (1)外部碎片 (2)内部碎片 2.连续内存分配算法 (1)首次适配 (2)最优适配 (3)最差适配 3.碎片整理方法 4.连续内存分配的缺点 二.非连 ...
- Linux内存管理:CMA(连续内存分配)(DMA)
目录 什么是CMA 数据结构 CMA区域 cma_areas 的创建 dts方式 command line方式 将CMA区域添加到Buddy System CMA分配 <Linux内存管理:什么 ...
最新文章
- 研究生第一篇科研论文常犯问题总结
- linux ”我的草稿“
- mediarecorder添加时间戳_[Paper] 自动驾驶中相机和激光雷达的时间戳误差标定
- werkzeug中服务器处理请求的实现
- HDU - 4686 Arc of Dream(矩阵快速幂,水题)
- UVA12325Zombie's Treasure Chest 宝箱
- 76Byte让你的JQuery更快
- LeetCode-----反转链表
- TensorFlow函数(四)tf.trainable_variable() 和 tf.all_variable()
- ECMAScript 6细说转码的常见的几种方案
- Nginx 反向代理解决浏览器跨域问题
- 服务器内存傲腾基本参数信息,服务器傲腾内存
- 【为什么需要FabricPath】FabricPath是思科 Nexus交换机上的一项技术特性,其目标是在保证二层环境的前提下,提高性能。来看看为什么数据中心需要FabricPath?
- Online Judge系统(简称OJ)
- RK3328启动失败解决记录
- 沙之家的塔塔露有事寻求冒险者 (位运算 前缀和 差分
- 沉睡者IT - 抖音中视频计划赚钱项目初级教程
- 《C语言程序设计(第五版)》习题答案
- PTA Python习题 身份证号码输出性别与出生日期
- 用树莓派(等)为 USB Midi 键盘增添连接方式