页面置换算法的实现
1.最佳置换算法
实现思路
- 首先创建一个进程结构体,属性为该进程需要的页面序列和分配给该进程的物理块数量(个人认为,单进程就能实现,所以这个结构体不使用也可以)
- 在主函数中进行初始化,初始化结构体进程,之后用户输入序列和物理块数量,赋值给结构体的属性
- 置换算法函数,开始先将内存物理块填满,此时不算作页面置换,按顺序将几个页面加入内存物理块即可,之后开始判断序列中每一个页面是否在内存中,在的话则跳过,不在的话触发页面中断,此时需要判断将内存中的那个页面置换出去,我采用的方法是求出:此时(内存中的几个页面下一次出现的索引)与(当前内存所需要的页面的索引)的差值,将差值最大的替换掉,循环往复
- 还需写一下求上述差值的函数,看代码即可。
- 对于序列中的每个页面的处理采用循环实现
代码如下:
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
struct PCB {
vector<int> need_page;
int physical_num;
};
void show(PCB pcb, vector<int> memory, int change_sum);
int max_vector(vector<int> v);
int time_diff_sum(vector<int> need_page, int index);
void optimal(PCB& pcb, vector<int> memory);
int max_vector(vector<int> v) {
int temp = 0;
for (int i = 1; i < v.size(); i++) {
if (v[i] > v[temp]) temp = i;
}
return temp;
}
int time_diff_sum(vector<int> need_page, int index, vector<int> memory, int memory_in) {
int sum = 1000;
for (int i = index + 1; i < need_page.size(); i++) {
if (need_page[i] == memory[memory_in]) {
sum = i - index;
break;
}
}
return sum;
}
void optimal(PCB& pcb, vector<int> memory) {
int change_sum = 0;
int sum = 0;
for (int i = 0; i < pcb.physical_num; i++) {
memory.push_back(pcb.need_page[i]);
show(pcb, memory, change_sum);
}
vector<int> time_diff;
for (int i = pcb.physical_num; i < pcb.need_page.size(); i++) {
cout << "此时进行页号为 " << pcb.need_page[i] << "的操作------------------" << endl;
cout << " |" << endl;
int flag = 0;
for (int k = 0; k < memory.size(); k++) {
if (memory[k] == pcb.need_page[i]) {
flag = 1;
}
}
if (flag == 1) {
cout << "页面已在内存,没有发生置换!" << endl;
show(pcb, memory, change_sum);
continue;
}
cout << "页面不在内存中,触发缺页中断" << endl;
for (int j = 0; j < memory.size(); j++) {
sum = time_diff_sum(pcb.need_page, i, memory, j);
time_diff.push_back(sum);
}
int max_sum = max_vector(time_diff);
time_diff.clear();
cout << "页面" << memory[max_sum] << "被淘汰,状态位变为0" << endl;
memory[max_sum] = pcb.need_page[i];
cout << "页面" << pcb.need_page[i] << "进入内存物理块中,状态位变为1" << endl;
change_sum++;
show(pcb, memory, change_sum);
}
float persent_rate;
persent_rate = float(change_sum+3) / float(pcb.need_page.size());
cout << "(最佳置换算法)此序列下的缺页率为:" << persent_rate << setprecision(2) << endl;
}
void show(PCB pcb, vector<int> memory, int change_sum) {
cout << " " << endl;
cout << " -------此时内存中页面情况为------- " << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "----";
}
cout << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "| " << memory[i] << " ";
}
cout << "|" << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "----";
}
cout << endl;
cout << " 此时置换次数为:" << change_sum << "次" << endl;
cout << "| |" << endl;
cout << "-----------------------------------------" << endl;
cout << " " << endl;
cout << " " << endl;
}
int main() {
cout << " " << endl;
cout << " " << endl;
cout << " ***此算法为最佳置换算法***" << endl;
cout << " " << endl;
cout << " " << endl;
cout << "---进行进程和内存(物理块)和页面号引用串初始化---" << endl;
PCB pcb;
cout << "请输入页面号引用串(使用数字代表ID号)" << endl;
cout << "输入时ID号之间使用空格,输入完成后使用回车" << endl;
int cin_page_num;
char c;
while ((cin >> cin_page_num).get(c)) {
pcb.need_page.push_back(cin_page_num);
if (c == '\n')
break;
}
if (pcb.need_page.size() > 0)
cout << "页面号引用串初始化成功!" << endl;
cout << " " << endl;
cout << "请输入物理块数量(一般为3)" << endl;
int cin_physical_num = 0;
cin >> cin_physical_num;
pcb.physical_num = cin_physical_num;
if (pcb.physical_num != 0)
cout << "物理块数量初始化成功!" << endl;
cout << " " << endl;
vector<int> memory;
cout << "内存初始化成功" << endl;
cout << "---初始化完毕---" << endl;
cout << " " << endl;
optimal(pcb, memory);
return 0;
}
2.先进先出置换算法
实现思路
- 创建页面结构体,属性在代码中可见,还有需要的变量以及向量数组
- 创建页面结构体数组,并初始化,物理块初始化,内存初始化。
- 先进先出置换算法函数,同理,先将物理块填满,吗,每添加一个页面,都需要将内存中的每个页面的stay_time停留时间+1(我使用页面停留时间来判断那个最先进入页面),接下来是其余页面,判断是否需要页面置换,需要的话则比较内存中的页面的stay_time,值最大的说明最先进入内存,则淘汰,添加新的页面,注意每个页面的stay_time的+1。
- 输出函数中添加了每个页面的情况信息,状态位,访问位等
代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Page {
int stay_time;
int ID;
int memory_ID;
int status;
int visited;
};
vector<int> need_page;
vector<Page> memory;
int physical_num = -1;
Page page[50];
void fifo(Page page[], vector<Page> memory, vector<int> need_page);
void show(vector<Page> memory, int change_sum, Page page1);
void fifo(Page page[], vector<Page> memory, vector<int> need_page) {
int change_sum = 0;
for (int i = 0; i < need_page.size(); i++) {
if (memory.size() < physical_num) {
memory.push_back(page[i]);
memory[i].memory_ID = i;
memory[i].status = 1;
memory[i].visited = 1;
for (int k = 0; k < memory.size(); k++) {
memory[k].stay_time++;
}
cout << "--------------------------------------------" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "此时内存物理块未满,页面直接放入,无需置换!" << endl;
show(memory, change_sum, memory[i]);
}
else {
int flag = 0;
for (int j = 0; j < memory.size(); j++) {
if (memory[j].ID == page[i].ID) {
flag = 1;
break;
}
}
if (flag == 1) {
cout << "此时内存中已有该页面------------------------" << endl;
cout << " |" << endl;
cout << " |" << endl;
page[i].stay_time = 0;
page[i].memory_ID = -1;
page[i].status = 0;
page[i].visited = 1;
for (int k = 0; k < memory.size(); k++) {
memory[k].stay_time++;
}
show(memory, change_sum, page[i]);
}
else {
cout << "此时内存中没有该页面,需要进行置换----------" << endl;
cout << " |" << endl;
cout << " |" << endl;
int stay_time_max_index = 0;
for (int e = 0; e < memory.size(); e++) {
if (memory[e].stay_time > memory[stay_time_max_index].stay_time) {
stay_time_max_index = e;
}
}
for (int k = 0; k < memory.size(); k++) {
memory[k].stay_time++;
}
cout << "**页面" << memory[stay_time_max_index].ID << "被淘汰" << endl;
memory[stay_time_max_index] = page[i];
memory[stay_time_max_index].stay_time = 1;
memory[stay_time_max_index].memory_ID = stay_time_max_index;
memory[stay_time_max_index].status = 1;
memory[stay_time_max_index].visited = 1;
change_sum++;
cout << "**页面" << page[i].ID << "进入内存物理块" << endl;
show(memory, change_sum, memory[stay_time_max_index]);
}
}
}
float persent_rate;
persent_rate = float(change_sum + 3) / float(need_page.size());
cout << "(先进先出算法)此序列下的缺页率为:" << persent_rate << endl;
}
void show(vector<Page> memory, int change_sum, Page page1) {
cout << " " << endl;
cout << "此页面信息:" << endl;
cout << " ------ -------- -------- ------ ------" << endl;
cout << "|页面号|停留时间|物理块号|状态位|访问位|" << endl;
cout << " ------ -------- -------- ------ ------" << endl;
cout << "| " << page1.ID << " | " << page1.stay_time << " | " << page1.memory_ID
<< " | " << page1.status << " | " << page1.visited << " |" << endl;
cout << " ------ -------- -------- ------ ------" << endl;
cout << " " << endl;
cout << " -------此时内存中页面情况为------- " << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "----";
}
cout << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "| " << memory[i].ID << " ";
}
cout << "|" << endl;
for (int i = 0; i < memory.size(); i++) {
cout << "----";
}
cout << endl;
cout << " 此时置换次数为:" << change_sum << "次" << endl;
cout << " |" << endl;
cout << " |" << endl;
cout << "--------------------------------------------" << endl;
cout << " " << endl;
cout << " " << endl;
}
int main() {
cout << " " << endl;
cout << " " << endl;
cout << " ***此算法为先进先出算法***" << endl;
cout << " " << endl;
cout << " " << endl;
cout << "---进行进程和内存(物理块)和页面号引用串初始化---" << endl;
cout << " " << endl;
cout << "请输入页面号引用串(使用数字代表ID号,个数上限为50)" << endl;
cout << "输入时ID号之间使用空格,输入完成后使用回车" << endl;
int cin_page_num;
char c;
while ((cin >> cin_page_num).get(c)) {
need_page.push_back(cin_page_num);
if (c == '\n')
break;
}
if (need_page.size() > 0)
cout << " " << endl;
cout << "页面号引用串初始化成功!" << endl;
for (int i = 0; i < need_page.size(); i++) {
page[i].ID = need_page[i];
page[i].stay_time = 0;
page[i].memory_ID = -1;
page[i].status = 0;
page[i].visited = 0;
}
cout << " " << endl;
cout << "请输入物理块数量(一般为3)" << endl;
int cin_physical_num = 0;
cin >> cin_physical_num;
physical_num = cin_physical_num;
if (physical_num != 0)
cout << " " << endl;
cout << "物理块数量初始化成功!" << endl;
cout << " " << endl;
cout << "内存初始化成功" << endl;
cout << " " << endl;
cout << "---初始化完毕---" << endl;
cout << " " << endl;
fifo(page, memory, need_page);
return 0;
}