实验 可变分区存储管理系统模拟
实验目的
可变分区分配是一种重要的存储管理思想,目前流行的操作系统采用的分段存储管理的基本思想就源自该方法。本实验的目的是通过编程来模拟一个简单的可变分区分配存储管理系统,经过实验者亲自动手编写管理程序,可以进一步加深对可变分区分配存储管理方案设计思想的理解。
实验要求
(1)编程实现简单的可变分区分配存储管理系统。要求:
a) 建立描述作业和内存分区的数据结构。
b) 初始信息输入,包括内存初始大小、各作业信息、使用哪种分区分配算法等。这些信息可以直接从键盘上输入,也可以从文件读取。
c) 程序实现空闲分区分配算法,程序初始化或运行过程中都应能指定算法。
d) 编程实现分区回收算法,对实验列出的几种分区回收情况都应该能处理。
e) 程序应能根据自己的内部时钟、作业到达时间和需要执行的时间,决定作业何时执行结束,并回收分区。
f) 实现分区移动算法,能在需要的时候合并空闲区。
g) 高级功能:为系统添加作业调度算法。
(2)使用本程序执行下面的一批作业,观察内存的分配和回收情况。系统可用内存的大小为2560K。
实验结果:
#define _CRT_SECURE_NO_WARNINGS // 关闭安全检查
#include <list>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int COUNT = 0; // 时间片
int NO = -1;
typedef struct job
{
string ID; // 作业名
int CPUTIME; // 已经运行时间
int RUNTIME; // 运行时间
int LENGTH; // 作业大小
} Job;
typedef struct busySpace
{
Job J;
int BEGIN;
int LENGTH;
int END;
} busySpace;
typedef struct freeSpace
{
int BEGIN; // 起始地址
int LENGTH; // 分区大小
int END; // 标志位
} freeSpace;
vector<busySpace> FAILSPACE;
list<busySpace> BUSYSPACELIST;
vector<freeSpace> FREESPACETABLE;
void getTime()
{
cout << "\033[32m\n\n------------------------------------------------------------------------------" << endl;
cout << "\n======================当前时间片\t" << COUNT << "\t================================\n"
<< endl;
cout << "-------------------------------------------------------------------------------\033[0m\n"
<< endl;
}
// 时间片+1
void addTime()
{
COUNT++;
}
int FF(busySpace &b)
{
int i = 0;
for (i = 0; i < FREESPACETABLE.size(); i++)
{
if (FREESPACETABLE[i].LENGTH >= b.J.LENGTH)
{
if (FREESPACETABLE[i].LENGTH > b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[i].BEGIN;
b.END = b.BEGIN + b.LENGTH;
BUSYSPACELIST.push_back(b);
FREESPACETABLE[i].BEGIN = b.END;
// 更新该空闲分区大小
FREESPACETABLE[i].LENGTH = FREESPACETABLE[i].END - FREESPACETABLE[i].BEGIN;
}
// 删除这块空闲分区
else if (FREESPACETABLE[i].LENGTH == b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[i].BEGIN;
b.END = b.BEGIN + b.LENGTH;
BUSYSPACELIST.push_back(b);
vector<freeSpace>::iterator it = FREESPACETABLE.begin();
while (it != FREESPACETABLE.end())
{
// 找到这块空闲分区,并删除
if (it->BEGIN == FREESPACETABLE[i].BEGIN)
{
it = FREESPACETABLE.erase(it);
break;
}
it++;
}
}
break;
}
}
if (i == FREESPACETABLE.size())
i = -1;
// 返回空闲分区号,为了NF算法做准备
return i;
}
// NF算法
int NF(busySpace &b)
{
int i = NO + 1;
if (i >= FREESPACETABLE.size())
i = 0;
for (; i < FREESPACETABLE.size(); i++)
{
if (FREESPACETABLE[i].LENGTH >= b.J.LENGTH)
{
if (FREESPACETABLE[i].LENGTH > b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[i].BEGIN;
b.END = b.BEGIN + b.LENGTH;
BUSYSPACELIST.push_back(b);
FREESPACETABLE[i].BEGIN = b.END;
// 更新该空闲分区大小
FREESPACETABLE[i].LENGTH = FREESPACETABLE[i].END - FREESPACETABLE[i].BEGIN;
}
// 删除这块空闲分区
else if (FREESPACETABLE[i].LENGTH == b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[i].BEGIN;
b.END = b.BEGIN + b.LENGTH;
BUSYSPACELIST.push_back(b);
vector<freeSpace>::iterator it = FREESPACETABLE.begin();
while (it != FREESPACETABLE.end())
{
// 找到这块空闲分区,并删除
if (it->BEGIN == FREESPACETABLE[i].BEGIN)
{
it = FREESPACETABLE.erase(it);
break;
}
it++;
}
}
break;
}
}
if (i == FREESPACETABLE.size())
i = -1;
return i;
}
// BF算法
int BF(busySpace &b)
{
int i = 0;
int minLength = 999999; // 满足条件的最小分区大小
int minIndex = -1; // 满足条件的最小分区号
// 寻找满足条件的minIndex,minLength
for (; i < FREESPACETABLE.size(); i++)
{
if (FREESPACETABLE[i].LENGTH >= b.J.LENGTH)
{
if (minLength >= FREESPACETABLE[i].LENGTH)
{
minIndex = i;
minLength = FREESPACETABLE[i].LENGTH;
}
}
}
// 找到了
if (minLength > b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[minIndex].BEGIN;
b.END = FREESPACETABLE[minIndex].END;
BUSYSPACELIST.push_back(b);
FREESPACETABLE[minIndex].LENGTH = FREESPACETABLE[minIndex].END - FREESPACETABLE[minIndex].BEGIN;
}
else if (minLength == b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[minIndex].BEGIN;
b.END = FREESPACETABLE[minIndex].END;
BUSYSPACELIST.push_back(b);
vector<freeSpace>::iterator it = FREESPACETABLE.begin();
while (it != FREESPACETABLE.end())
{
// 找到这块空闲分区,并删除
if (it->BEGIN == FREESPACETABLE[minIndex].BEGIN)
{
it = FREESPACETABLE.erase(it);
break;
}
it++;
}
}
return minIndex;
}
// WF算法
int WF(busySpace &b)
{
int i = 0;
int maxLength = -1; // 满足条件的最小分区大小
int maxIndex = -1; // 满足条件的最小分区号
// 寻找满足条件的minIndex,minLength
for (; i < FREESPACETABLE.size(); i++)
{
if (FREESPACETABLE[i].LENGTH >= b.J.LENGTH)
{
if (maxLength <= FREESPACETABLE[i].LENGTH)
{
maxIndex = i;
maxLength = FREESPACETABLE[i].LENGTH;
}
}
}
// 找到了
if (maxLength > b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[maxIndex].BEGIN;
b.END = FREESPACETABLE[maxIndex].END;
BUSYSPACELIST.push_back(b);
FREESPACETABLE[maxIndex].LENGTH = FREESPACETABLE[maxIndex].END - FREESPACETABLE[maxIndex].BEGIN;
}
else if (maxLength == b.J.LENGTH)
{
b.BEGIN = FREESPACETABLE[maxIndex].BEGIN;
b.END = FREESPACETABLE[maxIndex].END;
BUSYSPACELIST.push_back(b);
vector<freeSpace>::iterator it = FREESPACETABLE.begin();
while (it != FREESPACETABLE.end())
{
// 找到这块空闲分区,并删除
if (it->BEGIN == FREESPACETABLE[maxIndex].BEGIN)
{
it = FREESPACETABLE.erase(it);
break;
}
it++;
}
}
return maxIndex;
}
// 创建新作业
void input()
{
int num;
busySpace b;
cout << "请输入作业的名称\t运行时间\t作业大小\t\n";
cin >> b.J.ID >> b.J.RUNTIME >> b.J.LENGTH;
b.J.CPUTIME = 0;
b.LENGTH = b.J.LENGTH;
cout << "请选择将采用的作业分配算法:\t1.FF算法\t2.NF算法\t3.BF算法\t4.WF算法\t" << endl;
cin >> num;
switch (num)
{
case 1:
NO = FF(b);
break;
case 2:
NO = NF(b);
break;
case 3:
NO = BF(b);
break;
case 4:
NO = WF(b);
break;
default:
cout << "输错了,拜拜" << endl;
break;
}
if (NO == -1)
{
// 把创建失败的作业挂起
FAILSPACE.push_back(b);
cout << "\033[31m分配失败\033[0m" << endl;
system("pause");
}
}
// 显示分区情况
void disp()
{
system("cls");
getTime();
cout << "\033[35m\n==============================空闲分区表====================================\033[0m\n"
<< endl;
cout << "分区号\t"
<< "分区大小\t"
<< "分区始址\t" << endl;
for (int i = 0; i < FREESPACETABLE.size(); i++)
{
cout << i << "\t" << FREESPACETABLE[i].LENGTH << "\t\t" << FREESPACETABLE[i].BEGIN << "\t" << endl;
}
cout << "\033[35m\n==============================已分配分区表====================================\033[0m\n"
<< endl;
list<busySpace>::iterator it = BUSYSPACELIST.begin();
cout << "作业号\t"
<< "已运行时间\t"
<< "所需时间\t"
<< "作业大小\t"
<< "始址\t"
<< "终址\t" << endl;
while (it != BUSYSPACELIST.end())
{
cout << it->J.ID << "\t" << it->J.CPUTIME << "\t\t" << it->J.RUNTIME << "\t\t" << it->J.LENGTH << "\t\t" << it->BEGIN << "\t" << it->END << "\t" << endl;
it++;
}
cout << "\033[35m\n=================================================================================\033[0m\n";
}
// 分区回收算法
void free(int begin, int end)
{
vector<freeSpace>::iterator it;
// case1
if (end <= FREESPACETABLE[0].BEGIN)
{
if (end < FREESPACETABLE[0].BEGIN)
{
it = FREESPACETABLE.begin();
freeSpace f;
f.BEGIN = begin;
f.END = end;
f.LENGTH = f.END - f.BEGIN;
FREESPACETABLE.insert(it, f);
}
// 向后合并
else if (end == FREESPACETABLE[0].BEGIN)
{
FREESPACETABLE[0].BEGIN = begin;
FREESPACETABLE[0].LENGTH = FREESPACETABLE[0].END - FREESPACETABLE[0].BEGIN;
}
return;
}
// case2
else if (begin >= FREESPACETABLE[FREESPACETABLE.size() - 1].END)
{
if (begin > FREESPACETABLE[FREESPACETABLE.size() - 1].END)
{
it = FREESPACETABLE.end();
freeSpace f;
f.BEGIN = begin;
f.END = end;
f.LENGTH = f.END - f.BEGIN;
FREESPACETABLE.insert(it, f);
}
else if (begin == FREESPACETABLE[FREESPACETABLE.size() - 1].END)
{
FREESPACETABLE[FREESPACETABLE.size() - 1].END = end;
FREESPACETABLE[FREESPACETABLE.size() - 1].LENGTH = FREESPACETABLE[FREESPACETABLE.size() - 1].END - FREESPACETABLE[FREESPACETABLE.size() - 1].BEGIN;
}
return;
}
// case3
else
{
int i;
it = FREESPACETABLE.begin();
for (i = 0; i < FREESPACETABLE.size() - 1; i++, it++)
{
if (begin >= FREESPACETABLE[i].END && end <= FREESPACETABLE[i + 1].BEGIN)
break;
}
// 与前不相邻,与后不相邻,直接插进去
if (begin > FREESPACETABLE[i].END && end < FREESPACETABLE[i + 1].BEGIN)
{
freeSpace f;
f.BEGIN = begin;
f.END = end;
f.LENGTH = f.END - f.BEGIN;
FREESPACETABLE.insert(it + 1, f);
}
// 合并前后两块分区
else if (begin == FREESPACETABLE[i].END && end == FREESPACETABLE[i + 1].BEGIN)
{
FREESPACETABLE[i].END = FREESPACETABLE[i + 1].END;
FREESPACETABLE[i].LENGTH = FREESPACETABLE[i].END - FREESPACETABLE[i].BEGIN;
FREESPACETABLE.erase(it + 1);
}
// 与前相邻,与后不相邻
else if (begin == FREESPACETABLE[i].END && end < FREESPACETABLE[i + 1].BEGIN)
{
FREESPACETABLE[i].END = end;
FREESPACETABLE[i].LENGTH = FREESPACETABLE[i].END - FREESPACETABLE[i].BEGIN;
}
// 与后相邻,与前不相邻
else if (begin > FREESPACETABLE[i].END && end == FREESPACETABLE[i + 1].BEGIN)
{
FREESPACETABLE[i + 1].BEGIN = begin;
FREESPACETABLE[i + 1].LENGTH = FREESPACETABLE[i + 1].END - FREESPACETABLE[i + 1].BEGIN;
}
return;
}
}
// 作业运行一个时间片
void run()
{
list<busySpace>::iterator it = BUSYSPACELIST.begin();
while (it != BUSYSPACELIST.end())
{
// 已运行时间+1
it->J.CPUTIME++;
// 调用分区回收算法
if (it->J.CPUTIME == it->J.RUNTIME)
{
getTime();
cout << "\033[31m作业[ " << it->J.ID << " ]已经完成\033[0m" << endl;
system("pause");
int begin = it->BEGIN;
int end = it->END;
// 删除该块空间上的作业
it = BUSYSPACELIST.erase(it); // erase返回下一个迭代器
it--;
free(begin, end);
}
it++;
}
}
// 检查挂起的作业是否有足够的空间运行
void check()
{
vector<busySpace>::iterator it;
for (it = FAILSPACE.begin(); it < FAILSPACE.end(); it++)
{
NO = FF(*it);
if (NO != -1)
{
it = FAILSPACE.erase(it);
it--;
}
}
}
// 初始化空闲分区表
void initFreeSpace()
{
freeSpace f;
f.BEGIN = 0;
f.END = 2560;
f.LENGTH = f.END - f.BEGIN;
FREESPACETABLE.push_back(f);
}
int main()
{
int operate;
initFreeSpace();
while (true)
{
check();
disp();
cout << "1.创建作业\n"
//<< "2.显示内存分配情况\n"
<< "2.结束该轮时间片\n"
<< endl;
cin >> operate;
switch (operate)
{
case 1:
input();
break;
// case 2:
// disp();
// break;
case 2:
addTime();
run();
break;
}
}
return 0;
}