操作系统实六(页面置换算法之LRU)

 

#include<stdio.h> 
#include <iostream> 
#include <stdlib.h>  
#define DataMax 100 //常量DataMax
#define BlockNum 10 // 常量BlockNum  
int DataShow[BlockNum][DataMax];//用于存储要显示的数组 
int DataShowEnable[BlockNum][DataMax];//用于存储数组中的数据是否需要显示 
int Data[DataMax];//保存数据 
int Block[BlockNum];//物理块 
int count[BlockNum];//计数器 
int N;//页面个数
int M;//最小物理块数 
int ChangeTimes;//缺页次数  
void DataInput();//输入数据的函数 
void DataOutput();//输出数据的函数
void LRU();//LRU函数  
int main(int argc, char* argv[]) 
{  
   DataInput(); 
   LRU();
   return 0;     
}  
void DataInput() 
{  
   int i,choice;  
   printf("请输入最小物理块数:");
   scanf("%d",&M); // 输入最小物理块数大于数据个数  
    while(M > BlockNum){   
       printf("物理块数超过预定值,请重新输入:");   
       scanf("%d",&M);  
    }
    printf("请输入页面的个数:");  
    scanf("%d",&N); // 输入页面的个数大于数据个数
    while(N > DataMax){   
       printf("页面个数超过预定值,请重新输入:");
       scanf("%d",&N); 
    }  
    printf("请选择产生页面访问序列的方式(1.随机 2.输入):"); 
    scanf("%d",&choice); 
    switch(choice){   
       case 1:   // 产生随机访问序列   
       for(i = 0;i < N;i++){     
         Data[i] = (int)(((float) rand() / 32767) * 10);// 随机数大小在0 - 9之间 
       }     
       system("cls");// 显示随机产生的访问序列  
       printf("\n随机产生的访问序列为:");  
       for(i = 0;i < N;i++){    
         printf("%d ",Data[i]);  
       }  
       printf("\n");  
       break; 
       case 2:   // 输入访问序列  
        printf("请输入页面访问序列:\n"); 
        for(i = 0;i < N;i++)  
          scanf("%d",&Data[i]);  
        system("cls");   // 显示输入的访问序列 
        printf("\n输入的访问序列为:"); 
        for(i = 0;i < N;i++){   
           printf("%d ",Data[i]);  
        }  
        printf("\n"); 
        break; 
       default: 
          while(choice != 1 && choice != 2){    
            printf("请输入1或2选择相应方式:");  
            scanf("%d",&choice); 
          }   
        break;  
   } 
}  

void DataOutput() 
{  
    int i,j;  // 对所有数据操作 
    for(i = 0;i < N;i++){   
      printf("%d ",Data[i]);  
    } 
    printf("\n"); 
    for(j = 0;j < M;j++){ 
     // 对所有数据操作
     for(i = 0;i < N;i++){   
       if( DataShowEnable[j][i] ) 
         printf("%d ",DataShow[j][i]); 
       else     
         printf("  "); 
     }   
     printf("\n"); 
    }
    printf("缺页次数: %d\n",ChangeTimes=ChangeTimes+M); 
    printf("缺页率: %d%%\n",ChangeTimes*100/N);
}   

void LRU()// 最近最久未使用置换算法 
{  
  int i,j; 
  int find; 
  int point;
  int temp; // 临时变量 
  int m = 1,n; 
  ChangeTimes = 0; 
  for(j = 0;j < M;j++){  
    for(i = 0;i < N;i++){  
      DataShowEnable[j][i] = 0;  // 初始化为false,表示没有要显示的数据 
    } 
  } 
  for(i = 0;i < M;i++){   
     count[i] =0;//1处  // 初始化计数器 
  } 
  // 确定当前页面是否在物理块中,在继续,不在置换 
  Block[0] = Data[0];
 for(i = 1;m < M;i++){   
     int flag = 1; 
       for(n = 0; n < m;n++){   
       if(Data[i] == Block[n]) 
       flag = 0; 
     }  
     if(flag == 0)continue; 
     Block[m] = Data[i];  
     m++; 
    }  // 对有所数据操作 
 for(i = 0;i < N;i++){  
 // 增加count 
   for(j = 0;j < M;j++){    
      count[j]++; //2
   }
   find = 0; // 表示块中有没有该数据 
   for(j = 0;j < M;j++){  
      if( Block[j] ==0){//3    
         count[j] = 0;  
         find = 1; 
       }  
   } 
   // 块中有该数据,判断下一个数据  
   if(j==M) continue;//4   // 块中没有该数据 
      ChangeTimes++; 
   // 因为i是从0开始记,而BlockNum指的是个数,从1开始,所以i+1  
   if( (i + 1) > M ){   
     //获得要替换的块指针 
     temp = 0; 
     for(j = 0;j < M;j++){    
       if( temp < count[j] ){   
          temp = count[j];  
          point = j; // 获得离的最远的指针   
       }  
     } 
    } 
    else point = i;
   // 替换 
   Block[point] = Data[i]; 
   count[point] = 0; // 保存要显示的数据 
    for(j=0;j<M;j++){  
      DataShow[j][i] = Block[j]; 
      DataShowEnable[i < M ?(j <= i ? j : i) : j][i] = 1; // 设置显示数据 
    }   
  } 
// 输出信息
  printf("\nLRU => \n"); 
  DataOutput(); 
}

 

posted @ 2020-04-24 21:50  薄眠抛却陈年事。  阅读(964)  评论(0编辑  收藏  举报