页面置换算法 FIFO和LRU 及各自的命中率

(1) 先进先出算法FIFO:该算法的实质是选择作业中在主存驻留时间最长的一页淘汰,这种算法容易实现,例如分配一个作业的存储块数为m,则只需建立一张m个元素的队列表Q(0)、Q(1)、…、Q(m-1)和一个替换指针。这个队列是按页调入主存的一页。如图4-1所示,某时刻调入主存四个块,(即m=4),它们按页进入主存的先后顺序为4、5、1、2,当需要置换时,总是淘汰替换指针所指向的那一页, 新调进的页面装入主存后,修改相应的队列元素,然后将替换指针往前移动,使其指向当前最老的一页。

(2) 最近最少使用页面淘汰算法(LRU):这是一种经常使用的方法,有多种不同的实施方案。这里采用不断调整页表链的方法,即总是淘汰页表链链首的页面,而把新访问的页面插入链尾。如果当前调用页面已在页表内,则把它再次调整到链尾。这样就能保证最近使用的页面总处于靠近链尾部分,而不常使用的页面被移到链首,逐个被淘汰。

#include<stdio.h>
#define N 100
#define M 12//作业数
#define ASSIGN 4//存储块数
//请求式分页存储算法
//队列
typedef struct Queue{
  int Q[N];//存储页面
  int front,rear;//队头和队尾
}Queue;
//链表
typedef struct AdjList{
  int data;
  struct AdjList *next;
}AdjList;
//初始化队列
void InitQueue(Queue *Q){
   Q->front=-1;
   Q->rear=0;
}
//加入队列
void EnterQueue(Queue *Q,int n){
  if(Q->front>=Q->rear){
    printf("插入失败\n");
  }else{
    Q->front++;
    Q->Q[Q->front]=n;
    Q->rear++;
  }
}
//出队
void OutQueue(Queue *Q){
  if(Q->front<0){
    printf("queue is empty\n");
  }else{
    Q->front--;
    Q->rear--;
  }
}
//在队列中查找
int CheckQueue(Queue *Q,int n){
  int i;
  if(Q->front<0){
     //printf("queue is empty\n");
  }else{
     for(i=0;i<Q->rear;i++){
        if(n==Q->Q[i]){
            return 1;
        }
     }
  }
  return 0;
}
//打印队列
void PrintQueue(Queue *Q){
  int i;
  if(Q->front<0){
     //printf("queue is empty\n");
  }else{
     printf("打印队列:");
     for(i=0;i<Q->rear;i++){
        printf("%d ",Q->Q[i]);
     }
     printf("\n");
  }
}
//先进先出并算命中率
void FIFO(int A[]){
   int i,num=0,k=0;
   Queue *Q=(Queue *)malloc(sizeof(Queue));
   InitQueue(Q);
   for(i=0;i<M;i++){
     if(CheckQueue(Q,A[i])==1){
        num++;
     }else{
        if(k<ASSIGN){
          EnterQueue(Q,A[i]);
        }else{
          OutQueue(Q);
          EnterQueue(Q,A[i]);
        }
        k++;
     }
     PrintQueue(Q);
   }
   printf("FIFO的命中率为%f\n",(float)num/M);
}
//插入链表 头插法,链尾为队首(逻辑上)
void AddTail(AdjList *L,int n){
  if(L!=NULL){
   AdjList *p=(AdjList *)malloc(sizeof(AdjList));
   p->next=L->next;
   p->data=n;
   L->next=p;

  }else{
    printf("链表为空\n");
  }
}
//删除链首
void deleteTail(AdjList *L){
  if(L!=NULL){
   AdjList *p=L;
   while(p->next->next!=NULL){
     p=p->next;
   }
   p->next=NULL;
  }else{
    printf("链表为空\n");
  }
}
//查找n,若在,则调整到队尾
int CheckChangeTail(AdjList *L,int n){
  if(L!=NULL){
   AdjList *p=L;
   while(p->next!=NULL){
        //printf("链表为空\n");
        if(p->next->data==n){
           p->next=p->next->next;
           AddTail(L,n);
           return 1;
        }
        p=p->next;
   }
   return 0;
  }
}
//打印链表、
void printTail(AdjList *L){
  if(L!=NULL){
   AdjList *p=L->next;
   printf("打印链表:");
   while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
   }
   printf("\n");
  }
}
//最近最少使用页面淘汰算法
void LRU(int A[]){
   int i,num=0,k=0;
   AdjList *L=(AdjList *)malloc(sizeof(AdjList));
   L->next=NULL;
   for(i=0;i<M;i++){
       //printf("链表为空\n");
      if(CheckChangeTail(L,A[i])==1){
        num++;
      }else{
        if(k<ASSIGN){
          AddTail(L,A[i]);
        }else{
          deleteTail(L);
          AddTail(L,A[i]);
        }
        k++;
      }
      printTail(L);
   }
   printf("LRU的命中率为%f\n",(float)num/M);
}
int main(){
   int i,A[N];
   for(i=0;i<M;i++){//随机产生个M个进程作业数,没次调用的页面在1-8之间
     A[i]=rand()%8+1;
     printf("%d ",A[i]);
   }
   printf("\n");
   FIFO(A);
   LRU(A);
}



  • 1
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值