LRU页面置换算法的两种实现方式
栈实现
1、各类数据结构
const int N = 100;
int stack[N];
int top;//栈顶指针
int MAXSIZE;//栈的最大容量
int num, num_z;//用于计算缺页率
2、各类函数的实现
int check_same(int id)//判断栈中是否有相同页面,若有返回此页面在战中的位置
{
for (int i = 0; i < top; i++)
{
if (id == stack[i])
{
return i;
}
}
return -1;
}
void push(int id)//入栈操作
{
if (check_same(id) == -1 && !full())//栈中没有此页面,且栈没有满
{
printf("发生中断,页面%d被调入\n", id);
stack[top++] = id;
num_z++;
}
else if (check_same(id) == -1 && full())//栈中没有此页面,且栈满,需要将最近最久未使用的元素即栈底元素调出
{
printf("发生中断,页面%d被页面%d替换\n", stack[0],id);
for (int i = 0; i < top; i++)
{
stack[i - 1] = stack[i];
}
stack[top - 1] = id;
num_z++;
}
else if (check_same(id) != -1)//栈中有此页面
{
printf("页面%d在内存中。不发生中断。刷新页面%d的驻留时间\n", id, id);
int pos = check_same(id);
for (int i = pos; i < top - 1; i++)
{
stack[i] = stack[i + 1];
}
stack[top - 1] = id;
}
}
void show_stack()//显示栈中页面及详细页面展示
{
int cnt = 0;
printf("---------------------------------\n");
printf("页面号: ");
for (int i = top - 1; i >= 0; i--)
{
printf("|%2d|", stack[i]);
}
printf("\n");
printf("驻留时间: ");
for (int i = top - 1; i >= 0; i--)
{
printf("|%2d|", cnt++);
}
printf("\n---------------------------------");
printf("\n\n");
}
void page_missing_rate()//计算缺页率
{
float tmp = (num_z * 1.0 / num) * 100;
printf("缺页率为:%.2f%%\n\n", tmp);
}
3、主函数
int main()
{
int ne = -1;
printf("******LRU页面置换算法(栈实现)******\n\n\n");
printf("请输入存储区块数:");
scanf("%d", &MAXSIZE);
printf("请输入要调入的页面:");
while (ne != 0)
{
num++;
scanf("%d", &ne);
printf("\n");
push(ne);
show_stack();
page_missing_rate();
printf("请输入要调入的页面:");
}
}
4、栈实现方式完整代码
#include<stdio.h>
const int N = 100;
int stack[N];
int top;//栈顶指针
int MAXSIZE;//栈的最大容量
int num, num_z;//用于计算缺页率
bool full()//判断栈是否已满
{
if (top == MAXSIZE)
return true;
return false;
}
int check_same(int id)//判断栈中是否有相同页面,若有返回此页面在战中的位置
{
for (int i = 0; i < top; i++)
{
if (id == stack[i])
{
return i;
}
}
return -1;
}
void push(int id)//入栈操作
{
if (check_same(id) == -1 && !full())//栈中没有此页面,且栈没有满
{
printf("发生中断,页面%d被调入\n", id);
stack[top++] = id;
num_z++;
}
else if (check_same(id) == -1 && full())//栈中没有此页面,且栈满,需要将最近最久未使用的元素即栈底元素调出
{
printf("发生中断,页面%d被页面%d替换\n", stack[0],id);
for (int i = 0; i < top; i++)
{
stack[i - 1] = stack[i];
}
stack[top - 1] = id;
num_z++;
}
else if (check_same(id) != -1)//栈中有此页面
{
printf("页面%d在内存中。不发生中断。刷新页面%d的驻留时间\n", id, id);
int pos = check_same(id);
for (int i = pos; i < top - 1; i++)
{
stack[i] = stack[i + 1];
}
stack[top - 1] = id;
}
}
void show_stack()//显示栈中页面及详细页面展示
{
int cnt = 0;
printf("---------------------------------\n");
printf("页面号: ");
for (int i = top - 1; i >= 0; i--)
{
printf("|%2d|", stack[i]);
}
printf("\n");
printf("驻留时间: ");
for (int i = top - 1; i >= 0; i--)
{
printf("|%2d|", cnt++);
}
printf("\n---------------------------------");
printf("\n\n");
}
void page_missing_rate()//计算缺页率
{
float tmp = (num_z * 1.0 / num) * 100;
printf("缺页率为:%.2f%%\n\n", tmp);
}
int main()
{
int ne = -1;
printf("******LRU页面置换算法(栈实现)******\n\n\n");
printf("请输入存储区块数:");
scanf("%d", &MAXSIZE);
printf("请输入要调入的页面:");
while (ne != 0)
{
num++;
scanf("%d", &ne);
printf("\n");
push(ne);
show_stack();
page_missing_rate();
printf("请输入要调入的页面:");
}
}
5、运行示例
寄存器实现
1、各类数据结构
const int N = 100;
int MAXSIZE;
int num, num_z;
const int reg_size = 8; //寄存器总位数
int reg[N]; //记录每个页面的移位寄存器代表的数值
int store[N];
int Sum;//记录已存入元素的个数
2、各类函数实现
void change_R() //改变页面R值
{
for (int i = 0; i < Sum; i++)
{
reg[i] >>= 1;
}
}
int check_same(int id) //寻找是否有相同页面,并返回该页面下标
{
for (int i = 0; i < Sum; i++)
{
if (id == store[i])
return i;
}
return -1;
}
bool full() //判断内存区是否已经装满
{
if (Sum == MAXSIZE)
return true;
else
return false;
}
int find() //寻找淘汰页面
{
int Min = INT_MAX;
int pos = -1;
int i;
for (i = 0; i < Sum; i++)
{
if (reg[i] < Min)
{
Min = reg[i];
pos = i;
}
}
return pos;
}
void page_input(int id)//装入页面
{
if (check_same(id) == -1 && !full()) //物理块没有使用完,且内存中没有此页面
{
printf("发生中断,页面%d被调入\n", id);
reg[Sum] = 1 << reg_size - 1;
store[Sum++] = id;
num_z++;
}
else if (check_same(id) == -1 && full()) //物理块已满,且内存中没有此页面
{
int pos = find();
printf("发生中断,页面%d被页面%d替换\n", store[pos], id);
store[pos] = id;
reg[pos] = 1 << reg_size - 1;
num_z++;
}
else if (check_same(id) != -1) //内存中有此页面
{
printf("页面%d在内存中,不发生中断,刷新页面%d的R值\n", id, id);
int pos = check_same(id);
reg[pos] = reg[pos] | 1 << reg_size - 1;
}
}
void show_store() //显示内存中的页面及详细信息展示
{
printf("---------------------------------\n");
printf("页面号: ");
for (int i = 0; i < Sum; i++)
{
printf("|%2d|", store[i]);
}
printf("\n");
printf(" R 值 : ");
for (int i = 0; i < Sum; i++)
{
printf("|%2d|", reg[i]);
}
printf("\n---------------------------------");
printf("\n\n");
}
void page_missing_rate() //计算缺页率
{
double tmp = num_z * 1.0 / num * 100;
printf("缺页率为:%.2f%%\n\n", tmp);
}
3、主函数
int main()
{
int ne_page = -1;
printf("******LRU页面置换算法(寄存器实现)******\n\n\n");
printf("请输入要分配的物理块数:");
scanf("%d", &MAXSIZE);
printf("请输入要调入的页面:");
while (ne_page != 0)
{
num++;
scanf("%d", &ne_page);
printf("\n");
page_input(ne_page);
show_store();
change_R();
page_missing_rate();
printf("请输入要调入的页面:");
}
}
4、寄存器实现方式完整代码
#include<stdio.h>
#include<limits.h>
const int N = 100;
int MAXSIZE;
int num, num_z;
const int reg_size = 8; //寄存器总位数
int reg[N]; //记录每个页面的移位寄存器代表的数值
int store[N];
int Sum;//记录已存入元素的个数
void change_R() //改变页面R值
{
for (int i = 0; i < Sum; i++)
{
reg[i] >>= 1;
}
}
int check_same(int id) //寻找是否有相同页面,并返回该页面下标
{
for (int i = 0; i < Sum; i++)
{
if (id == store[i])
return i;
}
return -1;
}
bool full() //判断内存区是否已经装满
{
if (Sum == MAXSIZE)
return true;
else
return false;
}
int find() //寻找淘汰页面
{
int Min = INT_MAX;
int pos = -1;
int i;
for (i = 0; i < Sum; i++)
{
if (reg[i] < Min)
{
Min = reg[i];
pos = i;
}
}
return pos;
}
void page_input(int id)//装入页面
{
if (check_same(id) == -1 && !full()) //物理块没有使用完,且内存中没有此页面
{
printf("发生中断,页面%d被调入\n", id);
reg[Sum] = 1 << reg_size - 1;
store[Sum++] = id;
num_z++;
}
else if (check_same(id) == -1 && full()) //物理块已满,且内存中没有此页面
{
int pos = find();
printf("发生中断,页面%d被页面%d替换\n", store[pos], id);
store[pos] = id;
reg[pos] = 1 << reg_size - 1;
num_z++;
}
else if (check_same(id) != -1) //内存中有此页面
{
printf("页面%d在内存中,不发生中断,刷新页面%d的R值\n", id, id);
int pos = check_same(id);
reg[pos] = reg[pos] | 1 << reg_size - 1;
}
}
void show_store() //显示内存中的页面及详细信息展示
{
printf("---------------------------------\n");
printf("页面号: ");
for (int i = 0; i < Sum; i++)
{
printf("|%2d|", store[i]);
}
printf("\n");
printf(" R 值 : ");
for (int i = 0; i < Sum; i++)
{
printf("|%2d|", reg[i]);
}
printf("\n---------------------------------");
printf("\n\n");
}
void page_missing_rate() //计算缺页率
{
double tmp = num_z * 1.0 / num * 100;
printf("缺页率为:%.2f%%\n\n", tmp);
}
int main()
{
int ne_page = -1;
printf("******LRU页面置换算法(寄存器实现)******\n\n\n");
printf("请输入要分配的物理块数:");
scanf("%d", &MAXSIZE);
printf("请输入要调入的页面:");
while (ne_page != 0)
{
num++;
scanf("%d", &ne_page);
printf("\n");
page_input(ne_page);
show_store();
change_R();
page_missing_rate();
printf("请输入要调入的页面:");
}
}
5、运行示例
小结
LRU页面置换算法是选择最近最久未使用的页面进行淘汰,需要有栈和寄存器两类硬件之一的支持。
1、在使用栈作为模拟最近最久未使用算法的支持设备时,把栈底元素作为最近最久未使用页面的页面编号,并编写相应的函数实现其功能。
2、在使用寄存器作为模拟最近最久未使用算法的支持设备时,R值最小的则是最近最久未使用页面的页面编号。可以利用位运算来模拟寄存器,从而实现这种算法。每当进程访问某物理块时,将该物理块所对应的数组中的数字的最高位置1,并且每隔一定的时间把所有数字右移一位。