操作系统OS-页面置换(FIFO,OPT,LRU)算法(c实现)
1. 算法原理
页面置换算法是操作系统内存管理的核心技术,当物理内存不足时,选择被替换页面的策略。目标是通过减少缺页中断提高系统性能。主要算法包括:
(1) 先进先出的算法(FIFO):选择在内存中驻留时间最久的页面予以替换。
(2) 最佳淘汰算法(OPT):选择永不使用或在未来最长时间内不再被访问的页面予以替换。
(3) 最近最久未使用算法(LRU):选择过去最长时间未被访问的页面予以替换。
2. 算法的数据结构

3. 算法和算法流程图
(1) 先进先出的算法(FIFO):
缺页中断 -> 选择最早进入的页面 -> 替换该页面
(2) 最佳淘汰算法(OPT):
缺页中断 -> 计算每个页面下次访问的时间 -> 选择最晚被访问的页面 -> 替换该页面
(3) 最近最久未使用算法(LRU):
缺页中断 -> 计算每个页面上次访问的时间 -> 选择最早被访问的页面 -> 替换该页面
4. 源程序
#include<stdio.h>
#define M 100
int mem[M]; //内存页面
int page[M] = {7,0,1,2,0,3,
0,4,2,3,0,3,2,1,2,0,1,7,0,1}; //读入页面
int memCap = 3; //内存容量
int pageNum = 20; //读入页面量
int lackNum; //缺页次数
void memInit(); //内存初始化
int isNeedSwap(int left,int right,int page); //检查是否需要置换
void show(int left,int right); //展示内存状态
void fifo(); //先进先出算法
int opt_getIndex(int currentNext); //opt获取被置换出的页面索引
void opt(); //最佳置换算法
int lru_getIndex(int currentPre); //lru获取被置换出的页面索引
void lru(); //最近最少使用算法
int main() {
puts("------------FIFO------------");
memInit();fifo();
puts("------------OPT------------");
memInit();opt();
puts("------------LRU------------");
memInit();lru();
}
void memInit() {
for(int i=0; i<memCap; i++)
mem[i] = -1;
}
int isNeedSwap(int left,int right,int page) {
for(int i=left; i<right; i++) {
if(mem[i] == page)
return 0; //如果有,无需置换,返回0
}
return 1; //返回1,需要置换
}
void show(int left,int right) {
printf("(");
for(int i=left; i<right; i++)
printf("<%d>", mem[i]);
printf(")\n");
}
void fifo() {
lackNum = 0;
int left=0,right=memCap; //队列左右索引
for(int i=0; i<pageNum; i++) {
printf("%d次读入(%d)",i+1,page[i]);
if(isNeedSwap(left,right,page[i])) {
lackNum++;
mem[right] = page[i];
left++; //队列左索引右移
right++; //队列右索引右移
}
printf("处理之后状态:");
show(left,right);
}
printf("缺页次数%d,缺页率%.2f\n",lackNum,(float)lackNum/pageNum);
}
int opt_getIndex(int currentNext) {
int nextTime[M]; //下次访问时间
int isFutureUse,index;
for(int i=0; i<memCap; i++) {
if(mem[i] == -1) return i;
else {
isFutureUse = 0; //假设未来没有使用
for(int j=currentNext; j<pageNum; j++) {
if(mem[i] == page[j]) {
isFutureUse = 1;
nextTime[i] = j; //记录使用时间
break;
}
}
if(!isFutureUse) nextTime[i] = M; //即未来未使用
}
}
index = 0;
//puts("");
//printf("<%d下次使用为%d>", mem[index], nextTime[index]);
for(int i=1; i<memCap; i++) {
//printf("<%d下次使用为%d>", mem[i], nextTime[i]);
if(nextTime[i] > nextTime[index])
index = i;
}
//printf("即将取出%d ",mem[index]);
return index;
}
void opt() {
lackNum = 0;
int left=0,right=memCap;
for(int i=0; i<pageNum; i++) {
printf("%d次读入(%d)",i+1,page[i]);
if(isNeedSwap(left,right,page[i])) {
lackNum++;
mem[opt_getIndex(i+1)] = page[i];
}
printf("处理之后状态:");
show(left,right);
}
printf("缺页次数%d,缺页率%.2f\n",lackNum,(float)lackNum/pageNum);
}
int lru_getIndex(int currentPre) {
int preTime[M]; //之前使用时间
int isPreUse,index;
for(int i=0; i<memCap; i++) {
if(mem[i] == -1) return i;
else {
isPreUse = 0; //假设之前未使用
for(int j=currentPre; j>-1; j--) {
if(mem[i] == page[j]) {
isPreUse = 1;
preTime[i] = j; //记录之前使用时间
break;
}
}
if(!isPreUse) preTime[i] = -M; //即之前未使用
}
}
index = 0;
//puts("");
//printf("<%d上次使用为%d>", mem[index], preTime[index]);
for(int i=1; i<memCap; i++) {
//printf("<%d上次使用为%d>", mem[i], preTime[i]);
if(preTime[i] < preTime[index])
index = i;
}
//printf("即将取出%d ",mem[index]);
return index;
}
void lru() {
lackNum = 0;
int left=0,right=memCap;
for(int i=0; i<pageNum; i++) {
printf("%d次读入(%d)",i+1,page[i]);
if(isNeedSwap(left,right,page[i])) {
lackNum++;
mem[lru_getIndex(i-1)] = page[i];
}
printf("处理之后状态:");
show(left,right);
}
printf("缺页次数%d,缺页率%.2f\n",lackNum,(float)lackNum/pageNum);
}

浙公网安备 33010602011771号