实验原理
- 请求分页式存储管理:这是一种虚拟内存技术,其中物理内存被分为固定大小的页框,逻辑内存也被分为同样大小的页。当程序需要访问一个虚拟页时,如果该页不在物理内存中,则会发生缺页中断,系统必须选择一个页框来替换。
- 页面置换算法:当发生缺页中断时,需要决定哪个页应该被置换出物理内存。常见的算法包括FIFO(先进先出)和LFU(最少使用)。
- FIFO算法:当需要置换页时,选择在内存中驻留时间最长的页。
- LFU算法:选择最长时间没有被引用的页进行置换。
实现代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n = 0;
enum SCHEDUAL
{
FIFO,
LRU
};
struct Job
{
string name;
int num_visit;
vector<int> visit_order;
vector<bool> miss_record;
vector<int> out_record;
vector<vector<int>> sched_record;
};
int menu()
{
cout << "**********请求分页式存储管理**********" << endl;
cout << " * 1. FIFO分配 *" << endl;
cout << " * 2. LRU分配 *" << endl;
cout << " * 0. 退出 *" << endl;
cout << "请输入选项:";
int choice;
do
{
cin >> choice;
if (choice != 1 && choice != 2 && choice != 0)
cout << "输入的选项不存在!请重新输入:" << endl;
} while (choice != 1 && choice != 2 && choice != 0);
return choice;
}
Job *inputNewJob()
{
Job *new_job = new Job;
cout << "请输入作业名:";
cin >> new_job->name;
cout << "请输入作业页面访问次数:";
cin >> new_job->num_visit;
new_job->visit_order.resize(new_job->num_visit, -1);
new_job->miss_record.resize(new_job->num_visit, false);
new_job->out_record.resize(new_job->num_visit, -1);
new_job->sched_record.resize(new_job->num_visit);
cout << "请输入作业页面访问顺序:";
for (int i = 0; i < new_job->num_visit; i++)
{
cin >> new_job->visit_order[i];
}
return new_job;
}
void printSchedualProcess(Job *job, SCHEDUAL schedual)
{
if (schedual == FIFO)
cout << "**********打印作业FIFO调度进入主存的过程**********" << endl;
else if (schedual == LRU)
cout << "**********打印作业LRU调度进入主存的过程**********" << endl;
cout << "作业名:" << job->name << endl;
cout << "作业调度过程:" << endl;
cout << setw(2) << "i:\t";
for (int i = 0; i < job->num_visit; i++)
{
cout << setw(2) << i << " ";
}
cout << endl << "page:\t";
for (int i = 0; i < job->num_visit; i++)
{
cout << setw(2) << job->visit_order[i] << " ";
}
cout << endl << "sched:\t";
for (int i = 0; i < n; i++)
{
for (int j = 0; j < job->num_visit; j++)
{
if (job->sched_record[j][i] != -1)
cout << setw(2) << job->sched_record[j][i] << " ";
else
cout << " ";
}
cout << endl << "\t";
}
int num_miss = 0;
for (int i = 0; i < job->num_visit; i++)
{
if (job->miss_record[i])
{
cout << setw(2) << "+" << " ";
num_miss++;
}
else
cout << " ";
}
cout << endl << "out:\t";
for (int i = 0; i < job->num_visit; i++)
{
if (job->out_record[i] != -1)
cout << setw(2) << job->out_record[i] << " ";
else
cout << " ";
}
cout << endl << "缺页中断率为:" << (1.0 * num_miss) / job->num_visit * 100 << "%" << endl;
}
void FIFOSchedualing(Job *job)
{
vector<int> sched_process;
int i = 0;
for (i = 0; i < n; i++)
{
job->miss_record[i] = true;
sched_process.push_back(job->visit_order[i]);
job->sched_record[i].assign(sched_process.begin(), sched_process.end());
job->sched_record[i].resize(n, -1);
}
for (i = n; i < job->num_visit; i++)
{
if (find(sched_process.begin(), sched_process.end(), job->visit_order[i]) == sched_process.end())
{
job->miss_record[i] = true;
job->out_record[i] = sched_process.front();
sched_process.erase(sched_process.begin());
sched_process.push_back(job->visit_order[i]);
}
job->sched_record[i].assign(sched_process.begin(), sched_process.end());
}
}
void LRUSchedualing(Job *job)
{
vector<int> sched_process;
vector<int> visit_record;
int i = 0;
for (i = 0; i < n; i++)
{
job->miss_record[i] = true;
sched_process.push_back(job->visit_order[i]);
visit_record.push_back(1);
for (auto it = visit_record.begin(); it != visit_record.end() - 1; it++)
*it += 1;
job->sched_record[i].assign(sched_process.begin(), sched_process.end());
job->sched_record[i].resize(n, -1);
}
for (i = n; i < job->num_visit; i++)
{
for (auto it = visit_record.begin(); it != visit_record.end(); it++)
{
*it += 1;
}
if (find(sched_process.begin(), sched_process.end(), job->visit_order[i]) == sched_process.end())
{
job->miss_record[i] = true;
int lru_index = 0;
for (int j = 0; j < n; j++)
{
if (visit_record[j] > visit_record[lru_index])
lru_index = j;
}
job->out_record[i] = sched_process[lru_index];
sched_process.erase(sched_process.begin() + lru_index);
visit_record.erase(visit_record.begin() + lru_index);
sched_process.push_back(job->visit_order[i]);
visit_record.push_back(1);
}
else
{
int visit_index = 0;
while (visit_index < n && sched_process[visit_index] != job->visit_order[i])
visit_index++;
visit_record[visit_index] = 1;
}
job->sched_record[i].assign(sched_process.begin(), sched_process.end());
}
}
int main()
{
cout << "请输入主存物理块的块数:";
cin >> n;
int choice = 0;
while (true)
{
choice = menu();
switch (choice)
{
case 1: {
Job *new_job = inputNewJob();
FIFOSchedualing(new_job);
printSchedualProcess(new_job, FIFO);
delete new_job;
break;
}
case 2: {
Job *new_job = inputNewJob();
LRUSchedualing(new_job);
printSchedualProcess(new_job, LRU);
delete new_job;
break;
}
case 0: {
return 0;
}
}
}
return 0;
}