实现提示:
1.最近没有使用页面淘汰算法NUR
(1)原理简述:
所谓“最近未使用”首先是要对“近”作一个界定,比如CLEAR_PERIOD=50,便是在CPU最近的50次进程页面处理工作中,找出这50次都没有处理到的页面;如果
⑴ 这样的页面只有一个,就将其换出,放入需处理的新页面;
⑵ 有不只一个这样的页面,在这些页面中任取一个换出(可以是下标最小的,或者下标最大的,都随便),放入需处理的页面;
⑶ 没有一个这样的页面,随意换出一个页面(可以是下标最小的,或者下标最大的,都随便)。
算法特点:有一个循环周期,每到达这个周期,所有页面存放是否被CPU处理信息的属性均被置于初始态(没有被访问)。
(2)图表描述:
还用前面的例子,某进程在硬盘上被划为5个页面,用1、2、3、4、5表示,而处理机处理它们的顺序为:
1、4、2、5、3、3、2、4、2、5
而内存可以控制的页面数为3(AP=3),CLEAR_PERIOD取5;循环周期内,如果所有内存页面均被CPU处理或有多个页面未被CPU处理,取页码最小的页面换出。
2.理想型淘汰算法OPT
(1)原理简述:
前提还是在分配的内存页面占满的情况下。所谓的最佳置换法是一种理想状况下的算法,它要求先遍历所有的CPU待处理的进程页面序列(实际上由于待处理的页面有时取决于先前处理的页面,所有很多情况下不可能得到完整的待处理页面序列。在这个层面上,才说该算法是理想的。),在这些页面中,如果有已经在内存当中,而CPU不再处理的,就将其换出;如果页面在内存中,并且CPU待处理,就取从当前位置算起,最后处理到的页面,将其换出,比如CPU待处理的页面序列号为:
1 | 3 | 2 | 2 | 4 | 5 | 2 | 5 | 1 | 4 | 3 | 4 | 1 | 1 | 5 | 5 | 3 | 4 | 2 | 1 |
已经处理了5个页面(底纹为灰色),那么页面5是第一个待处理的页面;2是第二个;1是第四个;4是第五个;3是第六个。那么页面3就是针对当前位置而言,最后处理到的页面。
(2)图表描述:
还用前面的例子,某进程在硬盘上被划为5个页面,用1、2、3、4、5表示,而处理机处理它们的顺序为:
1、4、2、5、3、3、2、4、2、5
而内存可以控制的页面数为3(AP=3),
代码实现:
//Lz毅
#include<iostream>
#include<string>
using namespace std;
#define M 10 //内存页最大长度
#define N 50 //处理的页面最大长度
typedef struct page
{
int name = 0;//存放的页号
//近期没有使用作为判断是否处理到0为未处理,1为处理
//最佳置换 从当前位置到需要处理的位置的距离 换出大的
int num = 0;
};
page pagelist[M];//内存页
int handle[N];//处理机处理的页面的顺序
int len;//handle页面的长度
int AP;//总页面数
int outputlist[M][N];//与算法无关方便查看 输出显示 按列存储 按行显示
void write(int i)//将显示结果保存 方便显示
{
for (int j = 0; j < AP; j++)
{
outputlist[j][i] = pagelist[j].name;
}
}
void NUR(int CLEAR_PERIOD)//最近没有使用页面淘汰算法
{
int i, j;
for (i = 0; i < AP; i++)//先把页面填满再开始替换
{
pagelist[i].name = handle[i];
pagelist[i].num = 1;
write(i);
}
for (; i < len; i++)//填满之后开始
{
if (i % CLEAR_PERIOD == 0)//每过一定时间标志就清零
{
for (j = 0; j < AP; j++)//清零
{
pagelist[j].num = 0;
}
}
for (j = 0; j < AP; j++)//查找页面是否已经在内存
{
if (pagelist[j].name == handle[i])
{
pagelist[j].num = 1;
break;
}
}
if (j == AP)//遍历完也没有找到 缺页
{
for (j = 0; j < AP; j++)//从头向后 找第一个周期内没访问的
{
if (pagelist[j].num == 0)//从头向后替换 替换第一个
{
pagelist[j].name = handle[i];
pagelist[j].num = 1;
break;
}
}
if (j == AP)//全都访问过 替换第一个
{
pagelist[0].name = handle[i];
pagelist[0].num = 1;
}
}
write(i);
}
}
void OPT()//最佳置换算法
{
int i, j;
for (i = 0; i < AP; i++)//先把页面填满再开始替换
{
pagelist[i].name = handle[i];
pagelist[i].num = 1;
write(i);
}
for (; i < len; i++)//填满之后开始
{
for (j = 0; j < AP && (pagelist[j].name != handle[i]); j++);//查找页面是否已经在内存
if (j == AP)//遍历完也没有找到 缺页
{
for (j = 0; j < AP; j++)//从头向后 计算当前到需要处理的位置的距离
{
pagelist[j].num = 0;
//从当前位置直到末尾 未到下一个需要处理的位置 值就+1
for (int k = i + 1; k < len && pagelist[j].name != handle[k]; k++, pagelist[j].num++);
}
int max = 0;
for (int k = 1; k < AP; k++)//找最大的
{
if (pagelist[max].num < pagelist[k].num)
{
max = k;
}
}
pagelist[max].name = handle[i];//替换最后处理到的页面
}
write(i);
}
}
void input()//输入
{
int i;
cout << "请输入处理机处理页面的顺序,输入 0 结束" << endl;
cin >> handle[0];
for (i = 1; handle[i - 1] != 0; i++)
{
cin >> handle[i];
}
len = i - 1;
cout << "请输入内存可以控制的总页面数:" << endl;
cin >> AP;
}
void output()//输出
{
cout << "\n处理页面顺序:" << endl << " ";
for (int i = 0; i < len; i++)
{
cout << handle[i] << " ";
}
cout << endl;
for (int i = 0; i < AP; i++)
{
cout << "内存页 " << i + 1 << " 号 ";
for (int j = 0; j < len; j++)
{
cout << outputlist[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int cho;//选择
int CLEAR_PERIOD;//循环周期
cout << "请输入选择的算法:\n1.最近没有使用页面淘汰算法\n2.最佳置换算法" << endl;
do {
cin >> cho;
if (cho != 1 && cho != 2)
{
cout << "输入不正确,请重试" << endl;
}
else
{
break;
}
} while (1);
input();
switch (cho)
{
case 1:
cout << "请输入循环周期:" << endl;
cin >> CLEAR_PERIOD;
NUR(CLEAR_PERIOD);
break;
case 2:
OPT();
break;
}
output();
return 0;
}
/*
测试数据一
1
1 4 2 5 3 3 2 2 5 0
3
5
测试数据二
2
7 5 1 2 5 3 5 4 2 3 5 3 2 1 2 5 1 7 5 1 0
3
*/
运行截图(测试样例见代码末):
1、最近没有使用页面淘汰算法
2、最佳置换算法