操作系统–动态分区存储管理
实验内容:
分区分配算法至少实现首次适应算法、最佳适应算法和最坏适应算法中的至少一种。熟悉并掌握各种算法的空闲区组织方式。 分区的初始化——可以由用户输入初始分区的大小。(初始化后只有一个空闲分区,起始地址为0,大小是用户输入的大小) 分区的动态分配过程:由用户输入作业号和作业的大小,实现分区过程。 分区的回收:用户输入作业号,实现分区回收,同时,分区的合并要体现出来。(注意:不存在的作业号要给出错误提示!) 分区的显示:任何时刻,可以查看当前内存的情况(起始地址是什么,大小多大的分区时空闲的,或者占用的,能够显示出来)。
代码:
#include <iostream>
#include <string>
#include <cstdio>
#include <map>
#include <cstdlib>
using namespace std;
const int MAX = 109;
const int INF = 1 << 30;
struct WORK
{
int work_id;
int work_size;
bool is_load;
bool is_delete;
WORK & operator=(const WORK &w)
{
work_id = w.work_id;
work_size = w.work_size;
is_load = w.is_load;
is_delete = w.is_delete;
return *this;
}
};
struct SUBAREA
{
int area_size;
int area_id;
bool exist_work;
WORK current_work;
SUBAREA & operator=(const SUBAREA &s)
{
area_size = s.area_size;
area_id = s.area_id;
exist_work = s.exist_work;
current_work = s.current_work;
return *this;
}
};
SUBAREA subarea[MAX];
WORK work[MAX];
int subarea_size;
int work_num;
int subarea_num;
map<int, bool> exist_work;
map<int, int> work_pos;
void init()
{
for(int i = 0; i < MAX; i++)
{
work[i].is_load = work[i].is_delete = false;
subarea[i].exist_work = false;
subarea[i].current_work.work_id = -1;
}
}
int order_insert_subarea(WORK w, int s_num)
{
int insert_num = -1;
int sum = 0;
int next_s = 0;
for(int i = 0; i < s_num; i++)
{
if(subarea[i].exist_work)
{
sum += subarea[i].current_work.work_size;
}
else if(w.work_size <= subarea[i].area_size && !subarea[i].exist_work)
{
sum += w.work_size;
subarea[i].current_work = w;
subarea[i].area_size = w.work_size;
subarea[i].exist_work = true;
subarea[i].area_id = i;
insert_num = i;
next_s = i + 1;
break;
}
}
if(insert_num != -1)
{
subarea_num ++;
subarea[next_s].area_id = next_s;
subarea[next_s].area_size = subarea_size - sum;
subarea[next_s].exist_work = false;
subarea[next_s].current_work.work_id = -1;
}
return insert_num;
}
int judge_worknum(int nu)
{
int exist_pos = -1;
for(int i = 0; i < subarea_num; i++)
{
if(subarea[i].current_work.work_id == nu)
{
exist_pos = i;
return exist_pos;
}
}
return exist_pos;
}
void recycle_work(int p)
{
int s_num = 0;
bool before = false;
bool next = false;
for(int i = 0; i < subarea_num - 1; i++)
{
if(i == p)
{
if( i != 0 && !subarea[i - 1].exist_work)
{
before = true;
s_num++;
}
if(!subarea[i + 1].exist_work)
{
next = true;
s_num++;
}
break;
}
}
if(before || next)
{
if(before && !next)
{
subarea[p - 1].exist_work = false;
subarea[p - 1].current_work.work_id = -1;
subarea[p - 1].area_size += subarea[p].area_size;
for(int i = p; i < subarea_num - 1; i++)
{
subarea[i] = subarea[i + 1];
subarea[i].area_id = i;
}
subarea_num --;
}
else if(!before && next)
{
subarea[p].exist_work = false;
subarea[p].current_work.work_id = -1;
subarea[p].area_size += subarea[p + 1].area_size;
for(int i = p + 1; i < subarea_num - 1; i++)
{
subarea[i] = subarea[i + 1];
subarea[i].area_id = i;
}
subarea_num --;
}
else
{
subarea[p - 1].exist_work = false;
subarea[p - 1].current_work.work_id = -1;
subarea[p - 1].area_size += (subarea[p].area_size + subarea[p + 1].area_size);
for(int i = p; i < subarea_num - 2; i++)
{
subarea[i] = subarea[i + 2];
subarea[i].area_id = i;
}
subarea_num -= 2;
}
}
else
{
subarea[p].exist_work = false;
subarea[p].current_work.work_id = -1;
}
}
int first_fit(WORK cur)
{
for(int i = 0; i < subarea_num; i++)
{
if(!subarea[i].exist_work && subarea[i].area_size >= cur.work_size)
{
return i;
}
}
return -1;
}
int best_fit(WORK cur)
{
int minn = INF;
int minn_id = -1;
for(int i = 0; i < subarea_num; i++)
{
if(!subarea[i].exist_work && subarea[i].area_size >= cur.work_size && subarea[i].area_size < minn)
{
minn = subarea[i].area_size;
minn_id = i;
}
}
return minn_id;
}
int worst_fit(WORK cur)
{
int maxx = -1;
int max_id = -1;
for(int i = 0; i < subarea_num; i++)
{
if(!subarea[i].exist_work && subarea[i].area_size >= cur.work_size && subarea[i].area_size > maxx)
{
maxx = subarea[i].area_size;
max_id = i;
}
}
return max_id;
}
void update_subarea(int posi, WORK cur)
{
int t = subarea[posi].area_size - cur.work_size;
if(t == 0)
{
subarea[posi].current_work = cur;
subarea[posi].exist_work = true;
return;
}
subarea[posi].area_size = cur.work_size;
subarea[posi].area_id = posi;
subarea[posi].current_work = cur;
subarea[posi].exist_work = true;
for(int j = subarea_num; j > posi + 1; j--)
{
subarea[j] = subarea[j - 1];
}
subarea[posi + 1].area_size = t;
subarea[posi + 1].area_id = posi + 1;
subarea[posi + 1].exist_work = false;
subarea[posi + 1].current_work.work_id = -1;
subarea_num++;
}
int main()
{
while(true)
{
init();
cout << "***********请选择你想实现的算法:***************" << endl;
cout << "************* 1、首次适应算法 ******************" << endl;
cout << "************* 2、最佳适应算法 ******************" << endl;
cout << "************* 3、最坏适应算法 ******************" << endl;
cout << "***************** 0、退出 *********************" << endl;
int sel;
cin >> sel;
if(sel == 0)
break;
cout << "请输入初始分区的大小:" << endl;
cin >> subarea_size;
subarea_num = 1;
subarea[0].area_id = 0;
subarea[0].area_size = subarea_size;
cout << "请输入待处理的作业个数: ";
cin >> work_num;
cout << "请输入各个作业信息(作业号 + 作业大小):" << endl;
for(int i = 0; i < work_num; i++)
{
cin >> work[i].work_id >> work[i].work_size;
exist_work[work[i].work_id] = true;
work_pos[work[i].work_id] = i;
}
int load_work_num = 0;
bool exist_unwork = false;
for(int i = 0; i < work_num; i++)
{
int t_num = order_insert_subarea(work[i], subarea_num);
if(t_num != -1)
{
load_work_num++;
work[i].is_load = true;
cout << "作业 " << work[i].work_id << " 成功装入分区 " << t_num << endl;
}
else
{
cout << "作业 " << work[i].work_id << "暂无可用分区,等待回收...." << endl;
exist_unwork = true;
}
}
cout << endl;
if(load_work_num != work_num)
{
cout << "存在 " << work_num - load_work_num << "个作业未装入,等待回收...." << endl;
}
while(load_work_num != work_num)
{
cout << "存在未装入的作业,请选择: 1、回收 其他、装入" << endl;
int se;
cin >> se;
if(se == 1)
{
int rework_num;
cout << "请输入待回收的作业号:";
cin >> rework_num;
int pos = judge_worknum(rework_num);
if(pos == -1)
cout << "您要回收的作业号不存在!" << endl;
else
{
recycle_work(pos);
cout << "回收后的分区状况:" << endl;
printf("%10s%10s%10s\n", "是否空闲", "分区编号", "分区大小");
for(int i = 0; i < subarea_num; i++)
printf("%10d%10d%10d\n", subarea[i].exist_work, subarea[i].area_id, subarea[i].area_size);
}
}
else
{
int load_id;
cout << "请输入要装入的作业编号:";
cin >> load_id;
int temp = judge_worknum(load_id);
if(temp != -1)
cout << "您要装入的作业已装入,请勿重复装入!" << endl;
else if(!exist_work[load_id])
cout << "您要装入的作业不存在!" << endl;
else
{
int suit_pos = work_pos[load_id];
int area_pos;
if(sel == 1)
{
area_pos = first_fit(work[suit_pos]);
if(area_pos == -1)
{
cout << "暂无可用分区!" << endl;
}
else
{
update_subarea(area_pos, work[suit_pos]);
load_work_num ++;
cout << "已成功装入分区,装入后的分区分配如下:" << endl;
printf("%20s%20s%20s%20s%20s\n", "是否空闲", "分区编号", "分区大小", "装入的作业号", "装入的作业大小");
for(int i = 0; i < subarea_num; i++)
printf("%20d%20d%20d%20d%20d\n", subarea[i].exist_work, subarea[i].area_id, subarea[i].area_size, subarea[i].current_work.work_id, subarea[i].current_work.work_size);
}
}
else if(sel == 2)
{
area_pos = best_fit(work[suit_pos]);
if(area_pos == -1)
{
cout << "暂无可用分区!" << endl;
}
else
{
update_subarea(area_pos, work[suit_pos]);
load_work_num ++;
cout << "已成功装入分区,装入后的分区分配如下:" << endl;
printf("%20s%20s%20s%20s%20s\n", "是否空闲", "分区编号", "分区大小", "装入的作业号", "装入的作业大小");
for(int i = 0; i < subarea_num; i++)
printf("%20d%20d%20d%20d%20d\n", subarea[i].exist_work, subarea[i].area_id, subarea[i].area_size, subarea[i].current_work.work_id, subarea[i].current_work.work_size);
}
}
else
{
area_pos = worst_fit(work[suit_pos]);
load_work_num ++;
if(area_pos == -1)
{
cout << "暂无可用分区!" << endl;
}
else
{
update_subarea(area_pos, work[suit_pos]);
cout << "已成功装入分区,装入后的分区分配如下:" << endl;
printf("%20s%20s%20s%20s%20s\n", "是否空闲", "分区编号", "分区大小", "装入的作业号", "装入的作业大小");
for(int i = 0; i < subarea_num; i++)
printf("%20d%20d%20d%20d%20d\n", subarea[i].exist_work, subarea[i].area_id, subarea[i].area_size, subarea[i].current_work.work_id, subarea[i].current_work.work_size);
}
}
}
if(load_work_num == work_num)
cout << "所有作业均已全部装入!" << endl;
}
}
system("pause");
system("clear");
}
return 0;
}
如有错误,欢迎指正~~
|