作業系統缺頁中斷FIFO、LRU、OPT演算法實現(對於頁框數量可以由使用者調控)
阿新 • • 發佈:2019-02-12
在之前,筆者隨意的用針對固定的三個頁框的情況下寫了一份兒基本程式碼,也就是熟悉一下演算法原理,大家可以忽略。
這一次寫的是實現使用者對於頁框數量實現自由的調控。
注意的是筆者使用的是C/C++的陣列,所以為了避免麻煩,在程式碼開始寫了一個#define max 5,當然對於這裡的5大家可以自己調整,由於手中的測試資料是12個數的陣列,所以這裡對於很多迴圈中都直接用了12,這是可以自由更改的,大家需要的時候可以自己實現或者用引數傳遞。演算法本身很簡單,只要稍微注意一下細節就行。廢話不多說,直接貼程式碼。
// Exercise4.cpp: 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; #define max 5 int pageList[12] = {4,3,2,1,4,3,5,4,3,2,1,5}; int checkPage(int page, int Page[], int k) { for (int i = 0;i < k;i++) if (page == Page[i]) return i; return -1; } /*前向查詢最近出現的頁面*/ int frontSearchPage(int page, int i) { for (int j = 0;j < i;j++) if (page == pageList[j]) return j; return i; } int backSearchPage(int page, int i) { for (int j = i;j >= 0;j--) if (page == pageList[j]) return j; return -1; } /*在pageList中查詢一個頁面*/ int searchPage(int page, int i) { i++; for(;i < 12;i++) if (pageList[i] == page) { return i; } return 999; } /*在pageList中統計頁面出現的次數*/ int countPage(int page, int i) { int count = 0; for (int j = i;j >= 0;j--) if (pageList[j] == page) count++; return count; } /*列印演算法*/ void display(int k, int *Spage[], int count, char empty[]) { cout << "List: \t"; for (int i = 0;i < 12;i++) cout << pageList[i] << "\t"; cout << endl; for (int i = 0;i < k;i++) { cout << "page" << i + 1 << ": \t"; for (int j = 0;j < 12;j++) { if (Spage[i][j] != -1) cout << Spage[i][j] << "\t"; else cout << "\t"; } cout << endl; } cout << endl << "empty :\t"; for (int i = 0;i < 12;i++) cout << empty[i] << "\t"; cout << endl; cout << endl << "共缺頁: " << count << "次" << endl; } /*先進先出演算法*/ void FIFO(int k) { int page[max]; int *sPage[max]; for (int i = 0; i < max;i++) { if (i < k) { sPage[i] = new int[12]; //對使用的區域進行記憶體分配,可增加項則不考慮 page[i] = -1; //-1表示在本實驗中需要用到的 } else page[i] = -2; //-2表示可增加項 } int count = 0; char empty[12]; for (int i = 0;i < 12;i++) { empty[i] = 'F'; for (int j = 0;j < k;j++) sPage[j][i] = -1; } for (int i = 0;i < 12;i++) { int num = checkPage(pageList[i], page, k); if (num >= 0) { for (int j = 0;j < k;j++) sPage[j][i] = sPage[j][i - 1]; continue; } else { for (int j = k - 1;j > 0;j--) page[j] = page[j - 1]; page[0] = pageList[i]; for (int j = 0;j < k;j++) sPage[j][i] = page[j]; empty[i] = 'T'; count++; } } display(k, sPage, count, empty); } /*OPT演算法*/ void OPT(int k) { int page[max]; int *sPage[max]; int count = 0; char empty[12]; for (int i = 0; i < max;i++) { if (i < k) { sPage[i] = new int[12]; //對使用的區域進行記憶體分配,可增加項則不考慮 page[i] = -1; //-1表示在本實驗中需要用到的 } else page[i] = -2; //-2表示可增加項 } for (int i = 0;i < 12;i++) { empty[i] = 'F'; for (int j = 0;j < k;j++) sPage[j][i] = -1; } sPage[0][0] = pageList[0]; page[0] = pageList[0]; count++; empty[0] = 'T'; for (int i = 1;i < 12;i++) { int num = checkPage(pageList[i], page, k); if (num >= 0) { for (int j = 0;j < k;j++) sPage[j][i] = sPage[j][i - 1]; continue; } else { int j; for(j = 1;j < k;j++) if (page[j] == -1) { for (int l = j;l > 0;l--) { page[l] = page[l - 1]; sPage[l][j] = page[l]; } sPage[0][i] = pageList[i]; page[0] = pageList[i]; break; } if (j == k) { int pageLoc[max]; for (int l = 0;l < k;l++) { pageLoc[l] = searchPage(page[l], i); } int far = 0; for (int l = 0;l < k;l++) { if (pageLoc[far] < pageLoc[l]) far = l; } for (int l = far;l > 0;l--) page[l] = page[l - 1]; page[0] = pageList[i]; for (int l = 0;l < k;l++) { sPage[l][i] = page[l]; } } count++; empty[i] = 'T'; } } display(k, sPage, count, empty); } /*LRU演算法*/ void LRU(int k) { int page[max]; int *sPage[max]; int count = 0; char empty[12]; for (int i = 0; i < max;i++) { if (i < k) { sPage[i] = new int[12]; //對使用的區域進行記憶體分配,可增加項則不考慮 page[i] = -1; //-1表示在本實驗中需要用到的 } else page[i] = -2; //-2表示可增加項 } for (int i = 0;i < 12;i++) { empty[i] = 'F'; for (int j = 0;j < k;j++) sPage[j][i] = -1; } sPage[0][0] = pageList[0]; page[0] = pageList[0]; count++; empty[0] = 'T'; for (int i = 1;i < 12;i++) { int countpage[max]; int num = checkPage(pageList[i], page, k); if (num >= 0) { //頁面處於該佇列中 for (int j = 0;j < k;j++) sPage[j][i] = sPage[j][i - 1]; for (int l = 0; l < k && sPage[l][i] != -1;l++) { for (int j = 0;j < k && sPage[j][i] != -1;j++) { int d1 = backSearchPage(page[l], i); int d2 = backSearchPage(page[j], i); if (d1 > d2) { int temp = page[l]; page[l] = page[j]; page[j] = temp; } } } for (int l = 0;l < k;l++) sPage[l][i] = page[l]; continue; } else { count++; empty[i] = 'T'; //對原始佇列中的頁面按照順序排列: //排序機制:1.讓出現次數較多的排在前列,2.在同等次數的情況下,讓最後一次出現靠後的排在前列 for (int l = 0;l < k && sPage[l][i] != -1;l++) countpage[l] = countPage(page[l], i); int far = 0; for (int l = 0; l < k && sPage[l][i] != -1;l++) { for (int j = 0;j < k && sPage[j][i] != -1;j++) { if (countpage[l] < countpage[j]) { int temp = page[l]; page[l] = page[j]; page[j] = temp; } else if (countpage[l] == countpage[j]) { int d1 = frontSearchPage(page[l], i); int d2 = frontSearchPage(page[j], i); if (d1 < d2) { int temp = page[l]; page[l] = page[j]; page[j] = temp; } } } } for (int l = k - 1;l > 0;l--) page[l] = page[l - 1]; page[0] = pageList[i]; for (int l = 0;l < k;l++) sPage[l][i] = page[l]; } } display(k, sPage, count, empty); } int main() { int k; while (1) { cout << "輸入需要的頁框數(max = 5,輸入6退出): "; cin >> k; if (k == 6) { cout << "感謝使用" << endl; exit(0); } else { cout << "FIFO演算法: " << endl; FIFO(k); cout << endl; cout << "OPT演算法: " << endl; OPT(k); cout << endl; cout << "LRU演算法: " << endl; LRU(k); } } return 0; }