动态分区管理
动态分区管理的主存分配模拟系统的设计—最先适应法、最佳适应法、最坏适应法(选择1~3种),模拟实现内存的分配回收;能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等;能够选择分配或回收操作;并能显示完成内存分配或回收后内存空间的使用情况;能够显示进程在内存的存储地址、大小等。
// os_test1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "t1.h"
using namespace std;
int main()
{
initinput();//初始输入
showstable();
int choice;
while (true)
{
showmenu();
cin >> choice;
switch (choice)
{
case 1: //内存区及请求表显示
showstable();
break;
case 2: //添加进程
addprocess();
break;
case 3: //最先分配进程
zuixian();
break;
case 4: //最优分配进程
zuiyou();
break;
case 5: //最坏分配进程
zuihuai();
break;
case 6: //回收进程
releaseprocess();
break;
case 7: //退出
return 0;
default:
cout << "INPUT ERROR!" << endl;
break;
}
}
}
#pragma once
#include <iostream>
using namespace std;
/*
数据结构
*/
int ProcessNum = 0; //进程个数
int RAM = 0; //内存大小
typedef struct Ram_table //内存分区表(输出),链表结构
{
int rnum = 0; //分区号
int pnum=0; //进程编号
int length = 0; //长度大小
int begin = 0; //首址
int end = 0; //尾址
bool status = false; //分区状态,是否已经分配
Ram_table* next=NULL;
}Ramtable,*Rtable;
Rtable ramHead = new Ramtable,tail=NULL;//内存分区表,头节点无
Rtable p1 = NULL, q1 = NULL; //内存分区表中间变量
int ramnum = 0; //内存分区个数
typedef struct unP_table //请求表,未分配内存进程表(输出)
{
int pnum = 0; //进程编号
int length = 0; //长度大小
unP_table* next = NULL;
}unPtable,*Utable;
Utable unpHead = new unPtable;//请求表,头节点无
Utable p2 = NULL, q2 = NULL; //请求表中间变量
int unpnum = 0; //未分区进程数
typedef struct Free_table //空闲分区表(不输出)
{
int fnum = 0; //空闲区编号
int length = 0; //空闲区长度
int begin = 0; //空闲区首址
Free_table* next = NULL;
}Freetable,*Ftable;
Ftable freeHead = new Freetable;//空闲分区表,头节点无,通过内存分区表更新
Ftable p3 = NULL, q3 = NULL; //空闲分区表中间变量
int fnum = 0; //空闲区个数
/*
函数
*/
//初始输入函数
void initinput();
//显示内存分区表以及请求表
void showstable();
//菜单显示
void showmenu();
//增加进程
void addprocess();
//进程回收
void releaseprocess();
//最先进程分配
void zuixian();
//最优分配进程
void zuiyou();
//最坏分配进程
void zuihuai();
//更新内存分区表区号
void freshrnum()
{
int i = 0;
for (p1 = ramHead->next; p1 != NULL; p1 = p1->next,i++) {
p1->rnum = i;
}
}
//更新空闲表,通过内存分区表更新
void freshftable()
{
//重置空闲表
for (p3 = freeHead->next; p3!=NULL; )
{
q3 = p3;
p3 = p3->next;
delete q3;
}
fnum = 0; //空闲区个数重新统计
q3 = freeHead;
for (p1 = ramHead->next; p1 != NULL; p1 = p1->next) {
if (p1->status == false)
{
p3 = new Freetable;
p3->fnum = p1->rnum;
p3->length = p1->length;
p3->begin = p1->begin;
p3->next = NULL;
q3->next = p3; //连接上
q3 = p3;
fnum++;
}
}
}
/*
//更新请求表
void freshunptable()
{
//重置请求表
}
*/
//空闲表升序
void Ascending()
{
Ftable y;
Ftable q= freeHead->next;//前驱
Ftable p = q->next;
while (p!=NULL)
{
if (q->length > p->length) //当前p->next点小于前驱点
{
y = freeHead;
while (y->next->length < p->length ) //从前往后找插入点
{
y = y->next;
}
q->next = p->next; //为下一个排序数,p可脱离操作插入到前面
p->next = y->next; //插入点前后连接上
y->next = p;
p = q->next; //p指向下一个未排点
}
else
{
q = q->next;
p = p->next;
}
}
}
//空闲表降序
void Descending()
{
Ftable y;
Ftable q = freeHead->next;//前驱
Ftable p = q->next;
while (p != NULL)
{
if (q->length < p->length) //当前p->next点大于前驱点
{
y = freeHead;
while (y->next->length > p->length) //从前往后找插入点
{
y = y->next;
}
q->next = p->next; //为下一个排序数,p可脱离操作插入到前面
p->next = y->next; //插入点,前后连接上
y->next = p;
p = q->next; //p指向下一个未排点
}
else
{
q = q->next;
p = p->next;
}
}
}
//在内存分区表中找对应空闲项
void look(int begin,Rtable p)
{
//通过起始位置找到对应空闲区节点
for (p1 = ramHead->next; p1!=NULL; p1=p1->next)
{
if (begin==p1->begin)
{
p = p1;
return;
}
}
p = NULL;
}
//初始输入函数
void initinput()
{
cout << "内存大小:";
cin >> RAM;
cout << "初始进程个数:";
cin >> ProcessNum;
if (ProcessNum==0)
{
//初始内存表
ramnum++; //分区个数
p1 = new Ramtable;
p1->rnum = 0;
p1->length = RAM;
p1->begin = 0;
p1->end = RAM-1;
p1->next = NULL;
ramHead->next = p1;
//初始空闲表
fnum++;
p3 = new Freetable;
p3->fnum = p1->rnum;
p3->length = p1->length;
p3->begin = p1->begin;
p3->next = NULL;
freeHead->next = p3;
return; //无需分配
}
int sram = 0; //已经分配内存,控制内存区首址
cout << "请分别输入" << ProcessNum << "个进程所需要的内存空间:";
for (int i = 0; i < ProcessNum; i++)
{
int x = 0;//临时变量
cin >> x;
if (RAM>=x+sram) //按顺序分配neicun
{
ramnum++; //分区个数
p1 = new Ramtable;
p1->rnum = i;
p1->length = x;
p1->pnum = i+1;
p1->status = true; //该分区已经分配
p1->begin = sram;
p1->end = sram + p1->length-1;
p1->next = NULL;
sram += x;
if (ramHead->next == NULL) {
ramHead->next= p1;
q1 = p1;
}
else {
q1->next = p1;
q1 = p1;
}
}
else //内存不够分,剩余进程存入请求表
{
unpnum++; //未分配进程个数
p2 = new unPtable;
p2->pnum = i + 1;
p2->length = x;
if (unpHead->next == NULL) {
unpHead->next = p2; q2 = p2;
}
else {
q2->next = p2;
q2 = p2;
}
}
}
if ((q1->end+1)<RAM) //内存分区还有剩余空间
{
ramnum++;
p1 = new Ramtable;
p1->rnum = q1->rnum+1;
p1->length = RAM- (q1->end + 1);
p1->pnum = 0;
p1->status = false; //该分区未被分配
p1->begin = q1->end+1;
p1->end = p1->begin + p1->length-1;
p1->next = NULL;
if (ramHead->next == NULL) {
ramHead->next = p1; q1 = p1;
}
else {
q1->next = p1;
q1 = p1;
}
//加入空闲表
fnum++;
p3 = new Freetable;
p3->fnum = p1->rnum;
p3->length = p1->length;
p3->begin = p1->begin;
p3->next = NULL;
if (freeHead->next == NULL) {
freeHead->next = p3; q3 = p3;
}
else {
q3->next = p3;
q3 = p3;
}
}
}
//显示内存分区表以及请求表
void showstable()
{
cout << "---------------------------------------------------------" << endl;
cout << " 内存分区表 " << endl;
cout << "内存区号\t长度\t首址\t尾址\t状态\t使用进程编号" << endl;
for (p1 =ramHead->next; p1 != NULL; p1 = p1->next) {
cout << p1->rnum << "\t\t" << p1->length << "\t" << p1->begin << "\t" << p1->end << "\t";
if (p1->status == true)
cout << "使用\t" << p1->pnum << endl;
else
cout << "空闲\t" <<"NULL"<< endl;
}
cout << " 请求表 "<<endl;
cout << "进程编号\t长度" << endl;
for (p2 = unpHead->next; p2 != NULL; p2 = p2->next)
{
cout << p2->pnum << "\t\t" << p2->length<<endl;
}
cout << " 空闲表 " << endl;
cout << "内存区号\t长度\t首址" << endl;
for (p3 = freeHead->next; p3 != NULL; p3 = p3->next)
{
cout << p3->fnum << "\t\t" << p3->length << "\t" << p3->begin << endl;
}
cout << endl;
}
//菜单显示
void showmenu()
{
cout << "---------------------------------------------------------" << endl;
cout << "1.内存区,请求表,空闲表显示"<<endl;
cout << "2.添加进程"<<endl;
cout << "3.最先分配进程"<<endl;
cout << "4.最优分配进程" << endl;
cout << "5.最坏分配进程" << endl;
cout << "6.回收进程"<<endl;
cout << "7.退出:"<<endl;
cout << "请输入对应操作序号:";
}
//增加进程
void addprocess()
{
cout << "---------------------------------------------------------" << endl;
//添加到请求表后
cout << "请输入进程编号和长度:";
p2 = new unPtable;
cin >> p2->pnum;
cin>>p2->length;
for (q2 = unpHead; q2->next!=NULL; q2=q2->next) //找到尾巴
{}
q2->next = p2;
unpnum++; //未分配进程个数
cout << "添加成功!" << endl;
}
//进程回收
void releaseprocess()
{
cout << "---------------------------------------------------------" << endl;
//找到对应节点删掉,并合并空闲区
cout << "输入释放内存区号:";
int freenum;
cin >> freenum;
p1 = ramHead->next;
q1 = ramHead; //记录删除0节点前head
for (int i = 0; i < freenum && p1 != NULL; i++)找到对应节点
{
q1 = p1; //记录删除节点前节点
p1 = p1->next;
}
if (p1==NULL)
{
cout << "回收失败!"<<endl;
}
else //删掉,并合并空闲区
{
if (p1->status==true)
{
if (p1->next != NULL && p1->next->status == false) //合并下空闲区
{
p1->next->begin = p1->begin;
p1->next->length += p1->length;
//p1->next->end 不变
//p1->next->next
//p1->next->pnum
//p1->next->status
q1->next = p1->next; //连接上
}else //后面无,或者不空,只改当前节点状态
{
p1->pnum = 0;
p1->status = false; //该分区未分配
}
if (q1->status == false && q1 != ramHead) //合并上空闲区 //删除不是0号区
{
q1->end = q1->next->end;
q1->length += q1->next->length;
q1->next = q1->next->next; //连接上
p1 = q1; //保存当前空闲区节点,稍后加入空闲表中
}
//更新内存分区表区号
freshrnum();
//更新空闲表
freshftable();
}
else
{
//已经是空闲区
cout << "已经是空闲区";
}
}
}
//最先进程分配
void zuixian()
{
//每一次分配后空闲区合并,在排序
cout << "---------------------------------------------------------" << endl;
if (unpHead->next == NULL)
{
cout << "请求表为空!" << endl;
return;
}
//有请求项,进入循环
for (p2=unpHead->next,q2=unpHead; p2!=NULL ; ) //遍历请求项,q2指向请求项前一项
{
for (p1 = ramHead->next; p1 != NULL && p2 != NULL; p1 = p1->next) //遍历空闲区符合要求的项
{
if (p2->length <= p1->length && p1->status == false) //请求表项可以放入空闲项
{
if (p2->length < p1->length)
{
//剩余插入内存分区表
Rtable pp1 = new Ramtable; //临时
pp1->begin = p1->begin + p2->length; //剩余空区填入内存分区项
pp1->length = p1->length - p2->length;
pp1->next = p1->next;
pp1->end = p1->end;
p1->next = pp1;
}
//请求项获得内存,保存内存分区表
p1->end = p1->begin + p2->length - 1;
p1->length = p2->length;
p1->pnum = p2->pnum;
p1->status = true;
cout << "进程编号"<<p2->pnum<<"分配成功" << endl;
//分配成功项p2从请求表删除,q2位置不变,p2取下一项
Utable pp2;
pp2 = p2;
p2 = p2->next;
q2->next = p2;
delete pp2; //删除的节点释放内存
break;
}
}
//请求项还有,但是当前空闲区都不满足,分配失败
if (p1 == NULL && q2->next!=NULL)
{
cout << "内存不足了!" << endl;
break;
}
}
//更新内存分区表区号
freshrnum();
//更新空闲表
freshftable();
}
//最优分配进程 空闲区长度由小到大
void zuiyou()
{
//每一次分配后空闲区合并,在排序
cout << "---------------------------------------------------------" << endl;
if (unpHead->next == NULL)
{
cout << "请求表为空!" << endl;
return;
}
//空闲表升序
Ascending();
cout << " 升序空闲表 " << endl;
cout << "内存区号\t长度\t首址" << endl;
for (p3 = freeHead->next; p3 != NULL; p3 = p3->next)
{
cout << p3->fnum << "\t\t" << p3->length << "\t" << p3->begin << endl;
}
//有请求项,进入循环
for (p2 = unpHead->next, q2 = unpHead; p2 != NULL; ) //遍历请求项,q2指向请求项前一项
{
for (p3 = freeHead->next; p3 != NULL ; p3 = p3->next) //遍历升序空闲表符合要求的项
{
if (p2->length <= p3->length ) //请求表项可以放入空闲项,修改内存分区表
{
look(p3->begin,p1); //在内存分区表中找对应空闲项p1(p3->p1)
if (p2->length < p3->length)//剩余插入内存分区表
{
//剩余插入内存分区表
Rtable pp1 = new Ramtable; //临时
pp1->begin = p1->begin + p2->length; //剩余空区填入内存分区项
pp1->length = p1->length - p2->length;
pp1->next = p1->next;
pp1->end = p1->end;
p1->next = pp1;
}
//请求项获得内存,保存内存分区表
p1->end = p1->begin + p2->length - 1;
p1->length = p2->length;
p1->pnum = p2->pnum;
p1->status = true;
cout << "进程编号" << p2->pnum << "分配成功" << endl;
//分配成功项p2从请求表删除,q2位置不变,p2取下一项
Utable pp2;
pp2 = p2;
p2 = p2->next;
q2->next = p2;
delete pp2; //删除的节点释放内存
//更新空闲表
freshftable();
//空闲表升序
Ascending();
break;
}
}
//请求项还有,但是当前空闲区都不满足,分配失败
if (p3 == NULL && q2->next != NULL)
{
cout << "内存不足了!" << endl;
break;
}
}
//更新内存分区表区号
freshrnum();
//更新空闲表
freshftable();
}
//最坏分配进程 空闲区长度由大到小
void zuihuai()
{
//每一次分配后空闲区合并,在排序
cout << "---------------------------------------------------------" << endl;
if (unpHead->next == NULL)
{
cout << "请求表为空!" << endl;
return;
}
//空闲表降序
Descending();
cout << " 降序空闲表 " << endl;
cout << "内存区号\t长度\t首址" << endl;
for (p3 = freeHead->next; p3 != NULL; p3 = p3->next)
{
cout << p3->fnum << "\t\t" << p3->length << "\t" << p3->begin << endl;
}
//有请求项,进入循环
for (p2 = unpHead->next, q2 = unpHead; p2 != NULL; ) //遍历请求项,q2指向请求项前一项
{
//直接判断第一个节点是否满足当前请求项
p3 = freeHead->next;
//没有空白项
if (p3 == NULL )
{
cout << "内存不足了!" << endl;
break;
}
if (p2->length <= p3->length) //请求表项可以放入空闲项
{
look(p3->begin, p1); //在内存分区表中找对应空闲项p1(p3->p1)
if (p2->length < p3->length)//剩余插入内存分区表
{
//剩余插入内存分区表
Rtable pp1 = new Ramtable; //临时
pp1->begin = p1->begin + p2->length; //剩余空区填入内存分区项
pp1->length = p1->length - p2->length;
pp1->next = p1->next;
pp1->end = p1->end;
p1->next = pp1;
}
//请求项获得内存,保存内存分区表
p1->end = p1->begin + p2->length - 1;
p1->length = p2->length;
p1->pnum = p2->pnum;
p1->status = true;
cout << "进程编号" << p2->pnum << "分配成功" << endl;
//分配成功项p2从请求表删除,q2位置不变,p2取下一项
Utable pp2;
pp2 = p2;
p2 = p2->next;
q2->next = p2;
delete pp2; //删除的节点释放内存
//更新空闲表
freshftable();
//空闲表升序
Descending();
}
else
{
//最坏算法当前最大都不能满足,分配失败
cout << "内存不足了!" << endl;
break;
}
}
//更新内存分区表区号
freshrnum();
//更新空闲表
freshftable();
return;
}
磁盘调度
选择1~3种磁盘调度算法(先来先服务法、最短寻道时间优先、电梯算法)模拟实现磁盘调度;
能够输入当前磁头的位置、磁头移动方向、磁道访问请求序列等;
计算磁头移动的总磁道数;
能够显示磁盘调度结果(磁头依次访问的磁道号顺序等)。
// os_test2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "t2.h"
using namespace std;
int main()
{
int choice;
while (true)
{
cout << "1.输入数据" << endl;
cout << "0.退出" << endl;
cout << "输入:";
cin >> choice;
switch (choice)
{
case 1:
//初始
init();
//先来先服务算法
fcfs();
//最短寻道时间优先算法
sstf();
//扫描算法,电梯算法
scan();
break;
case 0: //退出
return 0;
default:
cout << "INPUT ERROR!" << endl;
break;
}
}
}
#pragma once
#include <iostream>
#include <cmath>
using namespace std;
int num=0; //磁道访问请求序列个数
int* list; //磁道访问请求序列
bool* isv; //磁道是否访问
int start; //读写头起始位置
int dic; //scan算法,磁头移动方向,1大,0小
/*
函数
*/
//初始
void init()
{
cout << "请输入磁道访问请求序列个数:" ;
cin >> num;
list = new int[num + 1]; //0号为空
isv = new bool[num + 1]; //0号为空
for (int i = 1; i <= num; i++)
{
isv[i] = false;
}
cout << "请输入磁道访问请求序列:" ;
int i = 1;
while (i<=num)
{
cin >> list[i];
i++;
}
cout << "请输入读写头起始磁道:" ;
cin >> start;
cout << "(scan算法)磁头移动方向,1大号,0小号:" ;
cin >> dic;
cout << endl;
}
//先来先服务算法
void fcfs()
{
cout << "--------------先来先服务算法" << endl;
int sum; //磁头走过的总道数
sum = abs(start - list[1]);
for (int i = 1; i < num; i++)
{
sum += abs(list[i] - list[i + 1]);
}
cout << "走道顺序:" << endl;
cout << start<<" ";
for (int i = 1; i <= num; i++)
{
cout << list[i] << " ";
}
cout << endl << "磁头走过的总道数:" << sum << endl<<endl;
}
//最短寻道时间优先算法
void sstf()
{
//优先选择距当前磁头最近的访问请求进行服务
cout << "--------------最短寻道时间优先算法" << endl;
int sum=0; //磁头走过的总道数
int *road=new int[num + 1]; //路径,0号存起点
road[0] = start;
int space = start; //当前磁道位置
for (int i = 1; i <= num; i++) //找到第i步磁道
{
int minlength = INT_MAX;
int minnum=0;
for (int j = 1; j <= num; j++) //寻找最短
{
if (abs(list[j] - space) < minlength && isv[j] == false)
{
minlength = abs(list[j] - space);
minnum = j;
}
}
road[i] = list[minnum];
space = road[i];
isv[minnum] = true;
sum += minlength;
}
cout << "走道顺序:" << endl;
for (int i = 0; i <= num; i++)
{
cout << road[i] << " ";
}
cout << endl << "磁头走过的总道数:" << sum << endl << endl;
}
//scan求最短路径,及总道数
void s(int &space,int *road,int &sum,int b,int e) //b,e路径起始结束,位置
{
for ( ; b <=e ; b++) //找到第i步磁道
{
int minlength = INT_MAX;
int minnum=0;
for (int j = 1; j <= num; j++) //寻找最短
{
if (dic==0)
{
if (abs(list[j] - space) < minlength && isv[j] == false &&
list[j] <= space) //小号方向
{
minlength = abs(list[j] - space);
minnum = j;
}
}
else
{
if (abs(list[j] - space) < minlength && isv[j] == false &&
list[j] > space) //大号方向
{
minlength = abs(list[j] - space);
minnum = j;
}
}
}
road[b] = list[minnum];
space = road[b];
isv[minnum] = true;
sum += minlength;
}
}
//扫描算法,电梯算法
void scan()
{
cout << "--------------电梯算法" << endl;
int sum=0; //磁头走过的总道数
int* road = new int[num + 1]; //路径,0号存起点
road[0] = start;
int space = start; //当前磁道位置
// int b =1 ; //走道当前走过数,除起点,从1开始
int e=0; //小号边的道数
for (int i = 1; i <= num; i++)
{
if (list[i] <= space)
{
e++;
}
}
for (int i = 1; i <= num; i++)
{
isv[i] = false; //访问情况初始
}
/// <summary>
/// 两种方向都显示
/// </summary>
cout << "走道顺序:" << endl;
dic=0;
//先小号方向
//scan求最短路径,及总道数
s(space, road, sum, 1, e);
dic = 1; //反向
s(space, road, sum, e + 1, num);
for (int i = 0; i <= num; i++)
{
cout << road[i] << " ";
}
cout << endl << "0磁头走过的总道数:" << sum << endl << endl;
for (int i = 1; i <= num; i++)
{
isv[i] = false; //访问情况初始
}
space = start; //当前磁道位置
sum = 0; //磁头走过的总道数
dic = 1;
//先大号方向
s(space, road, sum, 1, num - e);
dic = 0;
s(space, road, sum, num - e + 1, num);
for (int i = 0; i <= num; i++)
{
cout << road[i] << " ";
}
cout << endl << "1磁头走过的总道数:" << sum << endl <<endl;
//选择方向算法
//switch (dic)
//{
//case 0:
// //先小号方向
// //scan求最短路径,及总道数
// s( space, road, sum,1,e);
// dic = 1; //反向
// s(space, road, sum, e+1,num);
// break;
//case 1:
// //先大号方向
// s(space, road, sum, 1,num-e);
// dic = 0;
// s(space, road, sum, num-e+1,num);
// break;
//default:
// cout << "方向填写错误!" << endl;
// return;
//}
//
//cout << "走道顺序:" << endl;
//for (int i = 0; i <= num; i++)
//{
// cout << road[i] << " ";
//}
//cout << endl << "磁头走过的总道数:" << sum << endl << endl;
//cout << endl;
}```