在地址映射过程当中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,若是操做系统内存中没有空闲页面,则操做系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。而用来选择淘汰哪一页的规则叫作页面置换算法。算法
一个好的页面置换算法,应具备较低的页面更换频率。从理论上讲,应该保留最近重复访问的页面,将之后都再也不访问或者很长时间内再也不访问的页面调出。----百度百科
有点不清楚。。。。。就是每次发生缺页就将最先进入内存的页面换出,而后将刚调入的页面换入该物理块。数组
这个算法其实也很好判断。分享一个小技巧。内存分配了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"); }