Linux下C语言实现LRU页面替换算法

FIFO页面置换算法,即 最近最久未使用的页面置换。

主要思想

其设计主要思想是:换出最近一段时间内最久没有被使用过的页。利用已知的页访问情况,预测将来。基于局部性原理,算法强调:若某页被访问了,它可能马上还要被访问;若某页很长时间未被访问,则它在最近一段时间也不会被访问。

算法原理

算法实现原理:当某个进程发生缺页中断且主存没有空闲页面时,为了选择距离当前时间最近的一段时间内最久没有被访问的页(距离当前访问页面最远的页)被淘汰,我们设计一种数据结构

c[n][2],第一列表示页号,共有 n 页(页号 1~n),第二列表示每个页的计数值,其初值均为 0。

当访问某页时,如果该页在内存,则取计数值最大的且加 1,作为该页的计数值;

如果该页不在内存且内存有空闲页面,则将该页调入内存,且取计数值最大的且加 1,作为该页的计数值;

如果该页不在内存且内存没有空闲页面时,淘汰计数值最小的页(计数值最大的是刚刚被访问的页面,计数值最小的就是最近最久未被访问的页面),并将被淘汰页的计数值清零,然后将该页调入内存,并取计数值最大的且加 1,作为该页的计数值。

具体实现

假设某个进程 P有6个页,标号分别为1~6,在内存中分配给该进程4个页面,假设进程访问页的顺序为

1    2    3   4   5    6   1   3   2   4   6    5   4   1   3   5   6   2    3    5    6   2    1   4

预测结果为:

缺页次数:18

#include <stdio.h>
void max_value(int x,int cc[][2]);//函数声明,页表处理
int r_algorithm(int cc[][2]);//函数声明,选择页面淘汰算法
char cc[25];//Y 表示产生缺页中断,N 表示未产生缺页中断
void page_table(int page1,int c[6][2]);//打印页表
void main()
{
    int i,j,page,row = 0,col = 1;//b[row][col],行/列指针
    int k = 0;//记录缺页中断次数
    int a[24] = {1,2,3,4,5,6,1,3,2,4,6,5,4,1,3,5,6,2,3,5,6,2,1,4};//存放页的调度///顺序
    int b[4][25];//模拟内存(分配四个页面)
    int c[6][2] = {{1,0},{2,0},{3,0},{4,0},{5,0},{6,0}};//定义页表并赋初值
    int d[25],p = 0;//存放页面淘汰顺序,p 页面淘汰数组 d 的指针
    b[0][0] = 0;
    b[1][0] = 0;
    b[2][0] = 0;
    b[3][0] = 0;

//***************页面调度处理***************************************
    for(i = 0;i < 24;i++)
    {
        if(a[i]==b[0][i]||a[i]==b[1][i]||a[i]==b[2][i]|a[i]==b[3][i]){
        b[0][i+1] = b[0][i]; //将前一列数据复制到下一列
        b[1][i+1] = b[1][i];
        b[2][i+1] = b[2][i];
        b[3][i+1] = b[3][i];
        max_value(a[i],c); //处理页表,a[i]页面是刚被访问的页面
        page_table(a[i],c); //打印页表
        cc[i] = 'F';
        col++; //col 指向下一列
    }
    else
    { //页面不在内存
        if(row > 3)
        { //row > 3 表示内存已没有空闲页面
        page = r_algorithm(c); //返回淘汰的页面 page
        d[p] = page; //d[]存放被淘汰的页面
        p++;
        k++; //缺页中断次数
        b[0][i+1] = b[0][i]; //将前一列数据复制到下一列
        b[1][i+1] = b[1][i];
        b[2][i+1] = b[2][i];
        b[3][i+1] = b[3][i];
        cc[i] = 'Y';
        if(b[0][i+1] == page)
        b[0][i+1] = a[i];
        if(b[1][i+1] == page)
        b[1][i+1] = a[i];
        if(b[2][i+1] == page)
        b[2][i+1] = a[i];
        if(b[3][i+1] == page)
        b[3][i+1] = a[i];
        max_value(a[i],c); //访问 a[i]页面,i 页面是刚被访问的页面
        page_table(a[i],c); //打印页表
        }
    else
    {
        b[0][i+1] = b[0][i]; //将前一列数据复制到下一列
        b[1][i+1] = b[1][i];
        b[2][i+1] = b[2][i];
        b[3][i+1] = b[3][i];
        cc[i] = 'Y';
        b[row][col] = a[i]; //a[i]页面进入内存
        max_value(a[i],c); //访问 a[i]页面,i 页面是刚被访问的页面
        col++;
        k++; //缺页中断次数
        row++;
        page_table(a[i],c); //打印页表
        }
    }
 }
//================显示处理结果===================================
    printf("\n ");
    for(i = 0;i < 24;i++)
    printf("%2d",a[i]); //显示页面调度顺序
    printf("\n ========================================================================\n");
    for(j = 0;j < 25;j++)
    printf("%2d",b[0][j]);
    printf("\n ------------------------------------------------------------------------\n");
    for(j = 0;j < 25;j++)
    printf("%2d",b[1][j]);
    printf("\n -------------------------------------------------------------------------\n");
    for(j = 0;j < 25;j++)
    printf("%2d",b[2][j]);
    printf("\n --------------------------------------------------------------------------\n");
    for(j = 0;j < 25;j++)
    printf("%2d",b[3][j]);
    printf("\n --------------------------------------------------------------------------\n");
    printf(" ");
    for(j = 0;j < 25;j++)
    { //打印是否产生缺页中断
        printf(" ");
        putchar(cc[j]);
    }
    printf("\n 缺页中断次数:%2d\n",k);
    printf("\n 页面淘汰顺序:");
    for(j = 0; j < p;j++)
    {
        printf("%d",d[j]); 
        printf(" ");
    }//显示页面淘汰顺序
    printf("\n\n");
 }
//============访问的页面在内存的处理(页表处理)===================
    void max_value(int x,int cc[][2]){//x-页号:求页表中计数的最大值,并将该页面置
    //为最新访问页面
    int i, max;
    max = cc[0][1];
    for(i = 0;i < 6;i++)
    if(max < cc[i][1])
    max = cc[i][1];
    for(i = 0; i < 6;i++)
    if(cc[i][0] == x)
    cc[i][1] = max + 1;
    }
//============ 选择被淘汰的页面(页表处理)======================
int r_algorithm(int cc[6][2]){
    int i,min,row,p;
    for(i = 0;i < 6;i++) //查询第一个计数为非 0 的页面的计数值
    if(cc[i][1] != 0){
    min = cc[i][1];
    p = cc[i][0];
    row = i;
    break;
    }
    for(i = 0;i < 6;i++) //寻找计数值最小的页面
    if(min > cc[i][1]&&cc[i][1] != 0){
    min = cc[i][1];
    p = cc[i][0]; //最小数所对应的页号被淘汰
    row = i; //记录最小数所在的行
     }
    cc[row][1] = 0; //在页表中被淘汰的页面计数清零
    return(p); //返回被淘汰的页面-P
    }
// =================打印页表===================================
void page_table(int page1,int c[6][2]){
    int i;
    printf("页面调度顺序 page = %d\n",page1);
    for(i = 0; i < 6;i++)
    printf("%2d   %2d\n",c[i][0],c[i][1]);
}
程序运行结果

一共展现24个页面的调度,此处不一 一 粘图了

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值