在地址映射過程當中,若在頁面中發現所要訪問的頁面不在內存中,則產生缺頁中斷。當發生缺頁中斷時,若是操做系統內存中沒有空閒頁面,則操做系統必須在內存選擇一個頁面將其移出內存,以便爲即將調入的頁面讓出空間。而用來選擇淘汰哪一頁的規則叫作頁面置換算法。算法
一個好的頁面置換算法,應具備較低的頁面更換頻率。從理論上講,應該保留最近重複訪問的頁面,將之後都再也不訪問或者很長時間內再也不訪問的頁面調出。----百度百科
有點不清楚。。。。。就是每次發生缺頁就將最先進入內存的頁面換出,而後將剛調入的頁面換入該物理塊。數組
這個算法其實也很好判斷。分享一個小技巧。內存分配了k個物理塊,發生缺頁中斷將要往內存調入某個頁面的時候,在該頁面往前面數K個物理塊最前面的那個就會是要換出的,由於該頁面最長時間未被使用過。(可能前面會有重複的頁面,有幾個重複的頁面就再往前面多數幾個)
例如:裝入7,0,1,以後訪問2號頁面的時候會發生缺頁中斷。此時物理塊有三個,2號頁面前面有三個頁面,最前面的是7號頁面因此將7號頁面換出。學習
簡單的Clock算法最多訪問兩輪:
最壞狀況就是全部的頁面訪問位都是1,訪問1輪以後,所有訪問位都會被置爲0,那麼確定會找到一個頁面換出。編碼
此時頁面會有四種狀況:
1.未被訪問,未被修改,最佳淘汰。
2.未被訪問,被修改過。
3.被訪問過,未被修改。
4.被訪問過,被修改過。操作系統
1.尋找未被訪問,未被修改的頁面,不修改訪問位。找到則換出,找不到進行第二步。
2.尋找未被訪問,可是被修改過的頁面。此時,每次掃描頁面的時候,將全部訪問位置爲0。找到就返回,找不到就進行第三步。
3.重複第一次步驟,尋找未被訪問,未被修改的頁面,不修改訪問位。找到則換出,找不到進行第四步。
4.重複第二步。尋找未被訪問,可是被修改過的頁面。此時必定能夠找到。3d
首先是前面三個裝入,就省略掉了直接從第四次以後開始打印的。
指針
#include<stdio.h> #include<stdlib.h> #define MAX 20 // 定義做業序列的最大長度 #define num_alloacte 3 //內存分配給進程的物理塊數 , 也就是同一時刻最多有幾個頁面能夠在內存中 int work_list [MAX]; //存儲做業序列 int num; //存儲要輸入的序列的長度 int memory_alloacte [num_alloacte]; // 如今在進程中的頁面序列 int current; // 記錄已經分配的做業的下標 void input(){ //初始化做業序列 , 以及內存分配給進程的物理塊數 printf("請輸入做業的個數:"); scanf("%d",&num); if (num > MAX) { printf("序列過長"); return; } printf("請輸入做業序列:\n"); for(int i = 0;i < num; i ++){ scanf("%d",&work_list[i]); } for(int i = 0;i < MAX ; i ++){ memory_alloacte[i] = -1; } for(int i = 0;i < num_alloacte;i ++){ memory_alloacte[i] = work_list[i]; current = i; } } void print(int* work_list,int* memory_alloacte ){ printf("\t如今進程中的頁面序列:"); for(int i = 0; i < num_alloacte; i ++){ printf("%3d\t",*(memory_alloacte+i)); } printf("\t\t當前剩餘的做業序列:"); for(int i = current+1; i < num;i ++){ printf("%3d",*(work_list+i)); } printf("\n"); } int judge(){ int temp [num_alloacte]; //賦值一個臨時變量 記錄此時物理框中的做業號 int count = num_alloacte; //記錄臨時變量物理框中還剩下的個數 for(int i = 0;i < num_alloacte; i ++){ temp[i] = memory_alloacte[i]; } int cur = current + 1; while (cur < num) { for (int i = 0; i < num_alloacte; i++) { if(work_list[cur] == temp[i]){ //若是剩下的工做序列中 現有內存中的做業還會調用的話, 就將其的值置爲 -1 if(count == 1){ //此時內存中剩下的那個做業號確定是最長時間沒有調用過的,後者是之後不再會調用 return i; } temp[i] = -1; count --; break; } } cur ++; } //此時再來遍歷這個 臨時的物理塊中做業號的 數組 , 若是他的值不是 -1,就說明後面須要調用的做業中再也沒有這個做業了,因此 就能夠直接返回。 for(int i = 0;i < num_alloacte;i ++){ if(temp[i] != -1){ return i; } else { continue; } } return 0; } void change(){ int index; int flag = 0; for (int i = current + 1; i < num; i++) { for (int j = 0; j < num_alloacte; j++) //來判斷下一個做業是否已經在內存中 { if(work_list[i] == memory_alloacte[j]){ flag = 1; //是的話讓標誌位置爲1 break; } } if(flag == 0){ //說明不在內存中,會出現頁面中斷。須要進行換頁。 index = judge(); if(memory_alloacte[index] != work_list[i]){ memory_alloacte[index] = work_list[i]; } current ++; print(work_list,memory_alloacte); } else { flag = 0; current ++; print(work_list,memory_alloacte); continue; } } } int main(){ input(); change(); system("pause"); }