C語言實現FIFO算法與LRU算法

 在操作系統中,當程序在運行過程中,若其所要訪問的頁面不再內存中而需要把他們調入內存,但內存已無空閒空間時,爲了保證該進程能正常運行,系統必須從內存調出一頁程序或數據送磁盤的兌換區中。但哪一個頁面調出,須根據一定的算法確定。通常,把選擇換出頁面的算法稱爲頁面置換算法(Page-Replacement Algorithms).置換算法的好壞將直接影響到系統的性能。

   1) 先進先出(FIFO)頁面置換算法

       該算法總是淘汰最先進入內存的頁面,即選擇在內存中駐留時間最久的頁面予以淘汰。該算法實現簡單,只需把一個進程調入內存,按先後順序排成一個隊列,並設置一個指針,稱爲替換指針,使他總能指向最老的頁面。但該算法與進程與實際運行的規律不相適應,效率最差。

  2) 最近最久爲使用(LRU)算法

      LRU算法是根據頁面調入內存後的使用情況進行決策的。就是利用“最近的過去”作爲“最近的將來”的近似,因此是將最近最久未使用的頁面予以淘汰。該算法賦予每一個頁面一個訪問字段,用來記錄一個頁面自上次被訪問以來所經歷的時間t,當淘汰一個頁面時,選擇現有頁面中t值最大的,及最近最久爲使用的頁面予以淘汰。

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <stdio.h>
 
#define PAGES 12  /*頁面引用頁數*/
#define M 3      /*當前分配給改作業的物理塊數*/
//#define M 4
/*頁面引用串*/
int page[PAGES] =  {4,3,2,1,4,3,5,4,3,2,1,5};
int rel[M][PAGES];   /*存儲結果數組*/
/*內存物理塊結構體*/
typedef struct{
  int pnum;     /*該塊中所存的頁面號*/
  int tm;       /*從最近一次調入所經歷的時間*/
}PBlock;
/*初始化物理塊數組*/
void init(PBlock *pb)
{
  int i,j;
  //pb = (PBlock*)malloc(sizeof(PBlock)*M);
  for(i=0;i<M;i++){
    pb[i].pnum = -1;
    pb[i].tm = -1;
    for(j=0;j<PAGES;j++){
      rel[i][j] = -1;
    }
  }
}
/*打印結果數組*/
void printRelArr(int rel[M][PAGES])
{
  int i,j;
  for(i=0;i<M;i++){
    for(j=0;j<PAGES;j++){
      if(rel[i][j]==-1)
        printf("_ ");
      else
        printf("%d ",rel[i][j]);
    }
    printf("\n");
  }
}
/*打印一維數組*/
void printArr1(int *arr,int n)
{
    int i;
    for(i=0;i<n;i++){
      printf("%d ",arr[i]);
    }
    printf("\n");
}
/*查看頁面號爲num的頁面是否在內存塊中,存在返回1*/
int in_mem(int num,PBlock *pb,int m)
{
  int i;
  int b = 0;
  for(i=0;i<m;i++){
      if(pb[i].pnum == num){
        b = 1;
        break;
      }
  }
  return b;
}
/*FIFO 算法的實現,無需考慮時間*/
int fifo(PBlock *pb,int m)
{
  int lps=0;   /*缺頁次數*/
  double lpp;   /*缺頁率*/
  int p = 0;    /*替換指針*/
  int index =0;  /*頁面號索引*/
  while(index<PAGES){
      if(!in_mem(page[index],pb,M)){    //如果該頁面不在物理塊中
        pb[p].pnum = page[index];        /*將該頁面放入物理塊中*/
        p = (p+1)%M;                     /*替換指針移動*/
        lps++;                           /*卻也次數加 1*/
        for(int i=0;i<M;i++){
          rel[i][index] = pb[i].pnum;
        }
      }
      index++;
  }
  printf("FIFO算法所得缺頁次數爲 %d\n",lps);
  lpp = (double)lps/PAGES;
  printf("FIFO算法缺頁率爲 %0.4lf \n",lpp);
  printf("頁面號序列爲:\n");
  printArr1(page,PAGES);
  printf("結果數列爲:\n");
  printRelArr(rel);
  return 0;
}
/*獲得最近最久的塊*/
int getP(PBlock *pb,int p)
{
  int i;
  bool out = true;  //
  for(i=0;i<M;i++){
    if(pb[i].tm == -1){
      p = i;
      out = false;
      break;
    }
  }
  if(out){
    for(i=0;i<M;i++){
      if(pb[i].tm>pb[p].tm)
        p = i;
    }
  }
  return p;
}
int getEQnum(int num,PBlock *pb)
{
  int i;
  int in = -1;
  for(i=0;i<M;i++){
    if(pb[i].pnum == num){
      in = i;
      break;
    }
  }
  return in;
}
/*LRU算法*/
void lru(PBlock *pb,int m)
{
  int lps=0;   /*缺頁次數*/
  double lpp;   /*缺頁率*/
  int p = 0;    /*替換指針*/
  int index =0;  /*頁面號索引*/
  while(index<PAGES){
      if(!in_mem(page[index],pb,m)){   /*如果頁面不在物理塊中*/
        p = getP(pb,p);
        pb[p].pnum = page[index];
        pb[p].tm = 0;
        lps++;
        for(int i=0;i<M;i++){
          rel[i][index] = pb[i].pnum;
        }
      }else{                         /*如果頁面在物理塊中*/
        int in = getEQnum(page[index],pb);  /*獲取該頁面在物理塊中的索引*/
          pb[in].tm = 0;
      }
      int i;
      for(i=0;i<M;i++){
          if(i!=p&&pb[i].tm!=-1){
            pb[i].tm++;
          }
      }
      index++;
  }
  printf("LRU算法所得缺頁次數爲 %d \n",lps);
  lpp = 1.0*lps/PAGES;
  printf("LRU算法缺頁率爲: %0.4lf\n",lpp);
  printf("頁面號序列爲:\n");
  printArr1(page,PAGES);
  printf("LRU結果數組爲:\n");
  printRelArr(rel);
}
int main()
{
    //printArr(rel);
  PBlock pb[M];
  init(pb);
  fifo(pb,M);
  init(pb);
  lru(pb,M);
  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章