操作系统 页面置换算法FIFO与LRU的实现

简介: 操作系统 页面置换算法FIFO与LRU的实现

FIFO

FIFO算法是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

image.png

LRU

最近最久未使用(LRU)的页面置换算法是根据页面调入内存后的使用情况做出决策的,需要记录页面的访问时间。每当进程访问某页面时, 便将该页面的页面号从栈中移出,将它压入栈顶。因此,栈顶始终是最新被访问页面的编号,而栈底则是最近最久未使用页面的页面号。

image.png

代码实现

#include<conio.h> 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|\n") //表格控制
#define bsize 4     //物理块大小
#define psize 16     //进程大小
typedef struct page{ 
       int num;  //记录页面号
       int time;  //记录调入内存时间
}Page;                   //页面逻辑结构,结构为方便算法实现设计
Page b[bsize];            //内存单元数 
int c[bsize][psize];   //暂保存内存当前的状态:缓冲区
int queue[100];      //记录调入队列
int K;              //调入队列计数变量 
int phb[bsize] = {0};   //物理块标号
int pro[psize] = {0};     //进程序列号
int flag[bsize] = {0};  //进程等待次数(存放最久未被使用的进程标志)
int i = 0, j = 0, k = 0;   //i表示进程序列号,j表示物理块号
int m = -1, n = -1;       //物理块空闲和进程是否相同判断标志
int max = -1,maxflag = 0; //标记替换物理块进程下标
int count = 0;            //统计页面缺页次数
int* build(){
  //随机产生序列号函数
  printf("随机产生一个进程序列号为:\n");
  int i = 0;
    for(i=0; i<psize; i++){
    pro[i] = 10*rand()/(RAND_MAX+1)+1;
        printf("%d  ",pro[i]);
    }
    printf("\n");
  return(pro);
}
int searchpb(){
  //查找空闲物理块
  for(j=0; j<bsize; j++){
    if(phb[j] == 0){
           m = j; 
       return m;     
           break;
        } 
  }
  return -1;
}
int searchpro(){
  //查找相同进程
  for(j = 0; j < bsize; j++){
       if(phb[j] == pro[i]){
          n = j;
      return j;
       }
    }
  return -1;
}
void empty(){
  //初始化内存
  for(i=0;i<bsize;i++){
    phb[i]=0;
  }
    count=0;                //计数器置零
}
void FIFO(){
   //先进先出页面置换算法
    for(i = 0; i<psize; i++){ 
     m=searchpb();
     n=searchpro();
        for(j = 0; j < bsize;j++){
          //找flag值最大的
           if(flag[j]>maxflag){
                maxflag = flag[j];
                max = j;
            }
        }   
        if(n == -1){               
      //不存在相同进程
           if(m != -1){            
                //存在空闲物理块
          phb[m] = pro[i];   //进程号填入该空闲物理块
          count++;
                flag[m] = 0;
                for(j = 0;j <= m; j++){
                    flag[j]++;
                }
                m = -1;
           }
           else{               
                //不存在空闲物理块
              phb[max] = pro[i];
                flag[max] = 0;
                for(j = 0;j < bsize; j++){
                  flag[j]++;
                }
                max = -1;
                maxflag = 0;
                count++;
           }
       }
       else{                    
      //存在相同的进程
        phb[n] = pro[i];
            for(j = 0;j < bsize; j++){
         flag[j]++;
            }
            n = -1;
       }
        for(j = 0 ;j < bsize; j++){
        printf("%d  ",phb[j]);
        }
       printf("\n");
    }
    printf("缺页次数为:%d\n",count);
  printf("\n");
}
void Init(Page *b,int c[bsize][psize]){ 
  //初始化内存单元、缓冲区
    int i,j; 
    for(i=0;i<psize;i++){ 
        b[i].num=-1; 
        b[i].time=psize-i-1; 
    } 
    for(i=0;i<bsize;i++) 
        for(j=0;j<psize;j++) 
            c[i][j]=-1; 
} 
int GetMax(Page *b){ 
  //取得在内存中停留最久的页面,默认状态下为最早调入的页面
    int i; 
    int max=-1;
    int tag=0;
    for(i=0;i<bsize;i++){ 
        if(b[i].time>max){ 
            max=b[i].time; 
            tag=i; 
        } 
    } 
    return tag; 
}
int Equation(int fold,Page *b){ 
  //判断页面是否已在内存中
    int i; 
    for(i=0;i<bsize;i++){ 
        if (fold==b[i].num) 
            return i; 
    } 
    return -1; 
} 
void Lruu(int fold,Page *b){ 
  //LRU核心部分
    int i; 
    int val; 
    val=Equation(fold,b); 
    if (val>=0){ 
        b[val].time=0; 
        for(i=0;i<bsize;i++) 
            if (i!=val) 
                b[i].time++; 
    } 
    else{
        queue[++K]=fold; //记录调入页面
        val=GetMax(b); 
      b[val].num=fold; 
        b[val].time=0; 
        for(i=0;i<bsize;i++) 
            if (i!=val) 
                b[i].time++; 
    } 
}
void LRU(){
    int i,j; 
    K=-1; 
    Init(b, c); 
    for(i=0;i<psize;i++){ 
        Lruu(pro[i],b); 
        c[0][i]=pro[i]; 
        //记录当前的内存单元中的页面
            for(j=0;j<bsize;j++) 
                c[j][i]=b[j].num; 
    } 
    //结果输出 
    printf("内存状态为:\n"); 
    Myprintf; 
    for(j=0;j<psize;j++) 
      printf("|%2d ",pro[j]); 
        printf("|\n"); 
        Myprintf; 
        for(i=0;i<bsize;i++){ 
            for(j=0;j<psize;j++){ 
                if(c[i][j]==-1) 
                    printf("|%2c ",32); 
                else 
                    printf("|%2d ",c[i][j]); 
            } 
            printf("|\n"); 
        } 
        Myprintf; 
        printf("\n调入队列为:"); 
        for(i=0;i<K+1;i++) 
    printf("%3d",queue[i]); 
        printf("\n缺页次数为:%6d\n缺页率:%16.6f",K+1,(float)(K+1)/psize); 
}
int main()
{
  int sel;  
    do{ 
      printf("0、退出(Exit)\n");
      printf("1、产生随机序列\n");
      printf("2、最久未使用(LRU)\n");
      printf("3、先进先出(FIFO)\n");
      printf("<请选择所要执行的操作:(0)(1)(2)(3)>\n");
      scanf("%d",&sel);
      if(sel == 0){
        printf("退出 \n");
    }
    if(sel == 1){
      build();
    }
    if(sel == 2){
      printf("LRU\n");
      LRU();
      empty();
      printf("\n");
    }
    if(sel == 3){
      printf("FIFO\n");
      FIFO();
      empty();
      printf("\n");
    }
  }while(sel!=0);
}

效果图

image.png

先输入1,产生随机序列,模拟进程序号列

image.png

再输入2调用LRU

image.png

输入3调用FIFO

image.png

输入0退出


目录
相关文章
|
算法 Linux 数据处理
《操作系统》—— 处理机调度算法
《操作系统》—— 处理机调度算法
|
3月前
|
算法
操作系统LRU算法(最近最少使用算法)
操作系统LRU算法(最近最少使用算法)
22 0
|
1月前
|
存储 缓存 算法
从0开始回顾数据结构---LRU,LFU算法
题意解释 请为LFU缓存设计一个数据结构。支持两种操作:get和set。 ● get(key) : 如果key在缓存中,则返回key对应的值;否则返回-1; ● put(key, value): 如果key在缓存中,则更新key对应的值;否则插入(key, value),如果缓存已满,则先删除使用频率最小的key,如果有多个key具有相同的使用频率,则应该删除最久未使用的key。 C++代码 class LFUCache { public: struct Node { Node *left, *right; int key, val;
|
3月前
|
缓存 算法 NoSQL
Redis 为何使用近似 LRU 算法淘汰数据,而不是真实 LRU?
Redis 为何使用近似 LRU 算法淘汰数据,而不是真实 LRU?
29 0
|
3月前
|
存储 缓存 算法
数据结构与算法面试题:实现一个 LRU 缓存,支持如下操作:获取值、更新值、删除键值对和插入键值对
数据结构与算法面试题:实现一个 LRU 缓存,支持如下操作:获取值、更新值、删除键值对和插入键值对
28 0
|
3月前
|
算法
操作系统OPT算法(最佳页面替换算法)
操作系统OPT算法(最佳页面替换算法)
33 0
|
3月前
|
存储 缓存 算法
【算法与数据结构】LRU 算法
LRU(Least Recently Used),这种算法认为最近使用的数据是热点数据,下一次有很大概率会再次使用这个数据。而最近很少被使用的数据,很大概率下一次不会使用。所以当缓存容量满时,优先淘汰掉最近最少使用的数据。
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真
|
1月前
|
算法
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
23 2