【操做系统】页面置换算法(最佳置换算法)(C语言实现)

【操做系统】页面置换算法(最佳置换算法)(C语言实现)

(编码水平较菜,写博客也只是为了我的知识的总结和督促本身学习,若是有错误,但愿能够指出)

1.页面置换算法:

在地址映射过程当中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,若是操做系统内存中没有空闲页面,则操做系统必须在内存选择一个页面将其移出内存,以便为即将调入的页面让出空间。而用来选择淘汰哪一页的规则叫作页面置换算法。算法

一个好的页面置换算法,应具备较低的页面更换频率。从理论上讲,应该保留最近重复访问的页面,将之后都再也不访问或者很长时间内再也不访问的页面调出。----百度百科

2.具体的页面置换算法:

2.1 最佳置换算法:一个进程在内存的若干个页面中,哪个页面是将来最长时间内再也不被访问的,那么若是发生缺页中断时,就将该页面换出,以便存放后面调入内存中的页面。

在这里插入图片描述

1.这是计算机操做系统(第四版)中的一个例子。系统首先为进程分配了三个物理块。上面一排数字是做业号。在转满三个物理块后,要访问2号做业,2号做业不在内存,因此会发生缺页中断,而后系统须要将2号做业调入内存,可是此时物理块已经装满。
2.依据最佳置换算法,会将7号页换出(0号页在2号页后第1个就会被访问,1号页在2号页后第10个会被访问,7号页在2号页后第14个会被访问,7号页在已经装入内存的做业中是将来最长时间不会被访问的,因此换出7号页)。
3.后面依次类推。

2.2 先进先出算法:若是发生缺页中断,须要换出一个页面的时候,老是选择最先进入内存的页面,即选择在内存中驻留时间最久的页面进行换出。

在这里插入图片描述
有点不清楚。。。。。就是每次发生缺页就将最先进入内存的页面换出,而后将刚调入的页面换入该物理块。数组

2.3 最近最久未使用(LRU)置换算法:LRU算法是缺页中断发生时选择最久未使用的页面进行换出。

在这里插入图片描述
这个算法其实也很好判断。分享一个小技巧。内存分配了k个物理块,发生缺页中断将要往内存调入某个页面的时候,在该页面往前面数K个物理块最前面的那个就会是要换出的,由于该页面最长时间未被使用过。(可能前面会有重复的页面,有几个重复的页面就再往前面多数几个)
例如:装入7,0,1,以后访问2号页面的时候会发生缺页中断。此时物理块有三个,2号页面前面有三个页面,最前面的是7号页面因此将7号页面换出。学习

2.4Clock置换算法(没有动图,不太形象,就不举例子了,若是不太清楚,能够私信我。)

2.4.1简单的Clock置换算法:将全部页面经过连接指针链接成一个循环队列。而后须要为每个页面设置一个访问位。当某页被访问的时候,将访问位置为1。选择页面换出的时候,须要检查页面的访问位。若是是0,就将页面换出,若是是1,那么就将访问位置为0。

简单的Clock算法最多访问两轮:
最坏状况就是全部的页面访问位都是1,访问1轮以后,所有访问位都会被置为0,那么确定会找到一个页面换出。编码

2.42改进型Clock算法:将全部页面经过连接指针链接成一个循环队列。而后须要为每个页面设置一个访问位和一个修改位。访问位为0表示未访问过,为1表示访问过。修改位为0表示未修改过,为1表示修改过。

此时页面会有四种状况:
1.未被访问,未被修改,最佳淘汰。
2.未被访问,被修改过。
3.被访问过,未被修改。
4.被访问过,被修改过。操作系统

换出页面的时候:

1.寻找未被访问,未被修改的页面,不修改访问位。找到则换出,找不到进行第二步。
2.寻找未被访问,可是被修改过的页面。此时,每次扫描页面的时候,将全部访问位置为0。找到就返回,找不到就进行第三步。
3.重复第一次步骤,寻找未被访问,未被修改的页面,不修改访问位。找到则换出,找不到进行第四步。
4.重复第二步。寻找未被访问,可是被修改过的页面。此时必定能够找到。3d

也就是说,改进型Clock算法,最多扫描四轮队列。由于最坏的状况就是所有页面的访问位和修改位都是1的状况。在通过第二轮扫描以后页面的访问位已经都是0。因此第四轮必定能够找到一个页面换出。

3.最佳置换算法运行截图:

首先是前面三个装入,就省略掉了直接从第四次以后开始打印的。
在这里插入图片描述指针

4.代码

#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");
}
相关文章
相关标签/搜索