操作系统之页面置换算法(最佳置换OPT,先进先出FIFO,最近最久未使用LRU)


最近学习操作系统时,实验要求实现常见的三种页面置换算法,博主按照书上要求试着编写,实现了案例,并记录在博客随记中,以便后续自己复习并也给需要的同学分享参考一下!水平有限,若有错,请悄悄告诉博主!博主好立即改正。

 

 

最佳置换算法(optimal replacement,OPT)是从内存中选择今后不再访问的页面或者在最长一段时间后才需要访问的页面进行淘汰。如下例子:

根据页面走向依次处理,得到最终的置换结果如下图表,整个页面缺页次数为7,缺页率为7/12=58%。

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #define N 12
  5 #define B 3
  6 using namespace std;
  7 
  8 int pageArr[N]={1,2,3,4,1,2,5,1,2,3,4,5};//页面走向
  9 int block[B]={0};//物理块3个,其数值是页号
 10 typedef struct FLAG {
 11     int flags[B];
 12     int counts;
 13 } FLAG;
 14 
 15 void opt(int pageArr[],int block[]);
 16 int inBlock(int which);
 17 int findFar(int next);
 18 void Replace(int index,int value);
 19 void disPlay();
 20 
 21 int main(void){
 22     cout << "begin:" <<endl;
 23     opt(pageArr,block);
 24     cout << "end!" <<endl;
 25 return 0;
 26 }
 27 
 28 void opt(int pageArr[],int block[]){
 29     int getIndex;
 30     for(int i=0;i<N;i++){
 31         if(i<3){//前3页号#短缺#进队列
 32             block[i]=pageArr[i];
 33             printf("缺页:(null)-->%d\n",pageArr[i]);
 34         }
 35         else {
 36             if(i==3){
 37                 disPlay();
 38 
 39             }
 40             if(inBlock(pageArr[i])!=-1){//下一个页面if在物理块中返回index并跳过,反-1
 41                 disPlay();
 42 
 43                 continue;
 44             }
 45             getIndex=findFar(i+1);//从下一个页号,找到最远出现的页面,替换的下标
 46             if(getIndex==-1){
 47                 cout<<"error,not replace obj!"<<'\t';
 48             }
 49             else{
 50                 Replace(getIndex,pageArr[i]);//由下标找到上一组替换目标,用第二参数替换
 51                 disPlay();
 52 
 53             }
 54         }
 55     }
 56 return;
 57 }
 58 
 59 //替换block中的物理块
 60 void Replace(int index,int value){
 61     printf("缺页:%d--被替换为-->%d\n",block[index],value);
 62     block[index]=value;
 63 return;
 64 }
 65 
 66 
 67 //找到最远出现的页面
 68 int findFar(int next){
 69     int index=-1;//error,默认返回不存在的索引
 70     FLAG myflag;
 71     myflag.flags[0]=0;
 72     myflag.flags[1]=0;
 73     myflag.flags[2]=0;
 74     myflag.counts=0;
 75     int stop = N-next;
 76     while(stop--){
 77         index=inBlock(pageArr[next++]);
 78         if(index!=-1){
 79             myflag.flags[index]=1;
 80             myflag.counts++;
 81         }
 82         else if(myflag.counts==B-1){//有2个不缺值时
 83             break;
 84         }
 85     }
 86     for(index=0;index<B;index++){
 87         if(myflag.flags[index]==0)
 88             break;
 89     }
 90 return index;
 91 }
 92 
 93 
 94 //下一个页面if在物理块中返回index,反-1
 95 int inBlock(int which){
 96     //int i=0;
 97     //while(i<B)
 98     //    if(block[i++]==which)
 99     //    return i-1;
100     for(int i=0;i<B;i++){
101         if(block[i]==which)
102             return i;
103     }
104 return -1;
105 }
106 
107 //打印一元组
108 void disPlay(){
109     int i=0;
110     while(i<B){
111         printf("%d\t",block[i++]);
112     }
113     printf("\n");
114 return;
115 }

上面是博主使用C++(基本是C语法)编写的代码,运行结果如下:

//////////////////////////////////////////////////////////////////////////

begin:
缺页:(null)-->1
缺页:(null)-->2
缺页:(null)-->3
1 2 3
缺页:3--被替换为-->4
1 2 4
1 2 4
1 2 4
缺页:4--被替换为-->5
1 2 5
1 2 5
1 2 5
缺页:1--被替换为-->3
3 2 5
缺页:3--被替换为-->4
4 2 5
4 2 5
end!

//////////////////////////////////////////////////////////////////////////

 

 

先进先出算法:先进先出置换算法(first in first out,FIFO)是淘汰最先进入内存的页面,即选择在内存中驻留时间最长的页面进行淘汰的算法。

下面举个例子:

根据页面走向依次处理,得到最终的置换结果如上图表,整个页面缺页次数为9,缺页率为9/12=75%。

使用代码实现:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #define B 3
 5 #define N 12
 6 
 7 typedef struct flag{
 8     int blocks[B];
 9     int index;//预留但没用到
10 }FLAG;
11 using namespace std;
12 
13 //全局变量(共享)
14 int pageArr[N]={1,2,3,4,1,2,5,1,2,3,4,5};//页面走向
15 int block[B]={0};//物理块3个,其数值是页号
16 FLAG bflag={{0,0,0},-1};
17 
18 void disPlay();
19 int inBlock(int value);
20 void fifo();
21 int checkFlag();
22 
23 int main(){
24     cout<<"begin"<<endl;
25     fifo();
26     cout<<"end!"<<endl;
27     return 0;
28 }
29 //先进先出
30 void fifo(){
31     int i=0;
32     int getIndex;//物理块索引
33     int getflag;//flag索引
34     while(i<N){
35         getIndex=inBlock(pageArr[i]);
36         if(getIndex==-1){//缺页返回-1,不缺页返回index并下一个
37             cout<<"缺页:"<<pageArr[i]<<"\t\t";
38             if((getflag=checkFlag())!=-1){//检查呆的久的
39                 block[getflag]=pageArr[i];
40             }
41             else{
42                 block[i%B]=pageArr[i];
43             }
44         }
45         else{
46             bflag.blocks[getIndex]=1;
47         }
48         disPlay();
49         i++;
50     }
51 }
52 //检查是否在物理块中
53 int inBlock(int value){
54     int index=-1;
55     for(int i=0;i<B;i++){
56         if(block[i]==value){
57             index=i;
58             break;
59         }
60     }
61 return index;
62 }
63 //打印一组
64 void disPlay(){
65     for(int i=0;i<B;i++){
66         cout<<block[i]<<'\t';
67         //printf("%d\t",block[i]);
68     }
69     printf("\n");
70 }
71 
72 int checkFlag(){
73     int i=0;
74     int index=-1;
75     while(i<B){
76         if(bflag.blocks[i]==1){
77             bflag.blocks[i]=0;
78             index=i;
79             break;
80         }
81         i++;
82     }
83 return index;
84 }

运行结果:

//////////////////////////////////////////////////////////////////////////

begin
缺页:1    1 0 0
缺页:2    1 2 0
缺页:3    1 2 3
缺页:4    4 2 3
缺页:1    4 1 3
缺页:2   4 1 2
缺页:5    5 1 2
5 1 2
5 1 2
缺页:3    5 3 2
缺页:4    5 3 4
5 3 4
end!

//////////////////////////////////////////////////////////////////////////

 

 

最近最久未使用算法:先进先出置换算法是最佳置换算法之间的主要差别是,先进先出置换算法利用页面进入内存后的时间最为置换依据,而最佳置换算法是将来使用页面的情况。如果以最近的过去作为不就将来的近似,那么就可以把过去最长时间里不曾被使用的页面置换掉。它的实质是,当需要置换一页时,选择在最近的一段时间里最久没有使用的页面进行置换。这种算法就称为最近最久未使用(least recently used,LRU)算法。最近最久未使用算法与每个页面最后使用的时间有关。

根据页面走向依次处理,得到最终的置换结果如下图表,整个页面缺页次数为10,缺页率为10/12=83%。

下面是一个案例:

使用代码实现:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #define N 12
  4 #define B 3
  5 
  6 typedef struct flag{
  7     int fblock[B];//记录各个物理块时间戳
  8     int pflag;//指针
  9 }FLAG;
 10 using namespace std;
 11 
 12 //全局变量(共享)
 13 int pageArr[N]={1,2,3,4,1,2,5,1,2,3,4,5};//页面走向
 14 int block[B]={0};//物理块3个,其数值是页号
 15 FLAG myflag={{0},0};
 16 
 17 void lru();
 18 int inBlock(int value);
 19 void disPlay();
 20 int findMaxTime();
 21 void addStamp();
 22 
 23 
 24 int main()
 25 {
 26     cout<<"begin"<<endl;
 27     lru();
 28     cout<<"end!"<<endl;
 29     return 0;
 30 }
 31 
 32 void lru(){
 33     int i;
 34     int getIndex;
 35     int maxOfIndex;
 36     for(i=0;i<N;i++){
 37         if(i<B){//前三个页
 38             block[i]=pageArr[i];
 39             myflag.fblock[i]=B-i;
 40             cout<<"缺页:"<<pageArr[i]<<"\t\t";
 41         }
 42         else{
 43             getIndex=inBlock(pageArr[i]);
 44             if(getIndex==-1){//缺页
 45                 maxOfIndex=findMaxTime();
 46                 block[maxOfIndex]=pageArr[i];
 47                 myflag.pflag=maxOfIndex;
 48                 cout<<"缺页:"<<pageArr[i]<<"\t\t";
 49             }
 50             else{
 51                 myflag.pflag=getIndex;
 52             }
 53             addStamp();
 54         }
 55         disPlay();
 56     }
 57 }
 58 
 59 //给其他加时间戳
 60 void addStamp(){
 61     int i=0;
 62     while(i<B){
 63         if(i!=myflag.pflag)
 64             myflag.fblock[i]++;
 65         else
 66             myflag.fblock[i]=0;
 67         i++;
 68     }
 69 }
 70 
 71 //在物理块中就返回索引,否则返回-1
 72 int inBlock(int value){
 73     int index=-1;
 74     int i=0;
 75     while(i<B){
 76         if(block[i]==value){
 77             index=i;
 78             break;
 79         }
 80         i++;
 81     }
 82 return index;
 83 }
 84 
 85 //打印一组
 86 void disPlay(){
 87     for(int i=0;i<B;i++){
 88         printf("%d\t",block[i]);
 89     }
 90     printf("\n");
 91 }
 92 
 93 //找到时间戳最大的物理块下标
 94 int findMaxTime(){
 95     int i=0;
 96     int index=0;//默认第一个时间戳最大
 97     for(i=1;i<B;i++){
 98         if(myflag.fblock[index]<myflag.fblock[i])
 99             index=i;
100     }
101 return index;
102 }

运行结果:

//////////////////////////////////////////////////////////////////////////

begin
缺页:1   1 0 0
缺页:2   1 2 0
缺页:3   1 2 3
缺页:4   4 2 3
缺页:1   4 1 3
缺页:2   4 1 2
缺页:5   5 1 2
5 1 2
5 1 2
缺页:3     3 1 2
缺页:4     3 4 2
缺页:5     3 4 5
end!

//////////////////////////////////////////////////////////////////////////

posted @ 2018-11-24 22:09  抬头看看  阅读(16102)  评论(1编辑  收藏  举报