操作系统 三种页面置换算法

三种页面置换算法

一、算法描述
1.先进先出(FIFO)置换算法
(1)描述:FIFO算法是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。
(2)优点:该算法实现简单,只需要把一个进程已调入内存的页面按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。
(3)缺点:该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如:含有全局变量、常用函数、例程等的页面,FIFO算法并不能保证这些页面不被淘汰。
2.最佳(Optimal)置换算法
(1)描述:最佳置换算法是由Belady于1966年提出的一种理论上的算法。其所选择的被淘汰的页面将是以后永不使用的,或许是在最长(未来)时间内不再被访问的页面。
(2)优点:采用最佳置换算法通常可以保证获得最低的缺页率。
(3)缺点:人们目前通常还无法预知,一个进程在内存的若干个页面中,哪一个页面是未来最长时间内不再被访问的,因此,该算法是无法实现的,但可以利用该算法去评价其他算法。
3.LRU(Least Recently Used)置换算法
(1)描述:最近最久未使用(LUR)的页面置换算法是根据页面调入内存后使用情况做出决策的。由于无法预测各页面将来的使用情况,只能利用“最近的过去”做“最近的将来”的近似,因此,LUR置换算法是选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间t。当需要淘汰一个页面时,选择现有页面中t值最大的,及最近最久未使用的页面予以淘汰。
(2)优点:考虑程序访问的时间局部性,一般能有较好的性能,实际应用多。
(3)缺点:实现会需要较多的硬件支持,会增加硬件成本。
4、CLCOK算法又称为最近未使用算法(NUR) 每页设置一个访问位,再将内存中的所有页面都通过链接指针链接成一个循环队列;当某个页面被访问时,其访问位置1。淘汰时,检查其访问位,如果是0,就换出;若为1,则重新将它置0;再按FIFO算法检查下一个页面,到队列中的最后一个页面时,若其访问位仍为1,则再返回到队首再去检查第一个页面。

二、代码实现

#include <stdio.h>
#include <stdlib.h>

typedef struct progress
{
    int num;        //页号
    int time;        //等待时间,LRU算法会用到这个属性
}Pro;//结构体定义,为变量提供一个新别名,方便变量的定义

int n;        //页面个数
int m;        //系统分配给进程的物理块数

void print(Pro *page1);        //打印当前物理块中的页面
int  Search(int num1, Pro *memory1);    //在物理块memory1中查找页面号num1,如果找到,返回其在memory1中的下标,否则返回-1
int Max(Pro *memory1);
int optimal(int num,int tag,Pro *memory1,Pro *page1);

int main(void)
{
    int i;
    int curmemory;        //调入物理块中的页面个数
    int missNum;        //缺页次数
    float missRate;        //缺页率
    char c;                //得到用户的输入字符,来选择相应的置换算法

    Pro *page;            //定义一个名为page的Pro类型的指针变量,页面集
    Pro *memory;        //定义一个名为memory的Pro类型的指针变量,物理块

    printf("输入内存中的页面个数:");
    scanf("%d", &n);
    printf("输入系统为进程分配的最小物理块数:");
    scanf("%d", &m);

    page= (Pro*)malloc(sizeof(Pro)*n);//指针获取内存空间的大小
    memory= (Pro*)malloc(sizeof(Pro)*m);

    printf("输入页面个数为%d的页面序列:\n", n);
    for(i=0;i<n;i++)
    {
        scanf("%d", &page[i].num);
        page[i].time=0;            //等待时间开始默认为0
    }

    do{
        for(i=0;i<m;i++)        //初始化物理块中页面
        {
            memory[i].num=-1;                //页面为空用-1表示
            memory[i].time=-1;                //
        }

        printf("*****1-FIFO页面置换*****\n");
        printf("*****2-OPT页面置换*****\n");
        printf("*****3-LRU页面置换*****\n");
        printf("*****请选择操作类型(1,2,3),按其它键结束*****\n");
        fflush(stdin);//清空输入缓冲区
        scanf("%c", &c);//得到用户的输入字符,选择相应的置换算法
        i = 0;
        curmemory = 0;

        if(c=='1')            //FIFO页面置换
        {
            missNum = 0;
            printf("FIFO页面置换情况:   \n");
            for(i=0;i<n;i++)
            {
                if(Search(page[i].num,memory)<0)//若在物理块中没有找到该页面
                {
                    missNum ++;
                    memory[curmemory].num=page[i].num;
                    print(memory);
                    curmemory = (curmemory+1)%m;
                }
            }//end for
            missRate = (float)missNum/n;
            printf("缺页次数:%d   缺页率:  %f\n", missNum, missRate);

        }//end if

        if(c=='2')            //OPT页面置换
        {
            missNum = 0;

            printf("OPT页面置换情况:   \n");
            for(i=0;i<n;i++)
            {
                if(Search(page[i].num,memory)<0)//若在物理块中没有找到该页面
                {
                    if(i<m)
                        curmemory = i;//调入物理块中的页面号为第i个页面的页面号
                    else
                        curmemory = optimal(page[i].num,i,memory,page);
                    missNum ++;
                    memory[curmemory].num=page[i].num;
                    print(memory);
                    curmemory = (curmemory+1)%m;
                }
            }//end for
            missRate = (float)missNum/n;
            printf("缺页次数:%d   缺页率:  %.2f%%\n", missNum, missRate*100);


        }//end if

        if(c=='3')            //LRU页面置换
        {
            missNum = 0;

            printf("LRU页面置换情况:   \n");
            for(i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(memory[j].num>=0)
                        memory[j].time++;
                }
                if(Search(page[i].num,memory)<0)//若在物理块中没有找到该页面
                {
                    missNum ++;
                //    printf("%d \n",curmemory);
                    if(i<m)
                        curmemory = i;//调入物理块中的页面号为第i个页面的页面号
                    else
                        curmemory = Max(memory);//调入物理块中的页面号为最先在物理块中出现的页面号

                    memory[curmemory].num=page[i].num;
                    memory[curmemory].time = 0;
                    print(memory);
                    curmemory = (curmemory+1)%m;
                }
                else
                {
                    curmemory = Search(page[i].num,memory);
                    memory[curmemory].time=0;
                    curmemory = (curmemory+1)%m;
                }

            }//end for
            missRate = (float)missNum/n;
            printf("缺页次数:%d   缺页率:  %.2f%%\n", missNum, missRate*100);



        }//end if

    }while(c=='1'||c=='2'||c=='3');


    return 0;
}


void print(Pro *memory1)//打印当前的页面
{
    int j;

    for(j=0;j<m;j++)
        printf("%d ", memory1[j].num);
    printf("\n");
}

//在物理块memory1中查找页面号num1,如果找到,返回其在memory1中的下标,否则返回-1
int  Search(int num1,Pro *memory1  )
{
    int j;

    for(j=0;j<m;j++)
    {
        if(num1==memory1[j].num)
            return j;
    }
    return -1;
}

//替换掉物理块memory1中以后永不使用,或是未来在最长时间内不再被访问的页面号
int optimal(int num,int tag,Pro *memory1,Pro *page1)
{
    int k,j,min[500],min_k;
    for(k=0;k<m;k++)
        min[k] = 500;
    for(k=0;k<m;k++)
    {
        j = tag;//标记当前页号
        do{
            j++;
            if(j>n)
                break;
        }while(page1[j].num!=memory1[k].num);//当前页面号未在物理块中出现,向后搜索
        if(j<min[k])
        {

            min[k] = j;//找出以后永不使用,或是未来在最长时间内不再被访问的页面
        }
    }
    int max = 0;
    for(int t=1;t<m;t++)
    {
        if(min[t]>min[max])//物理块中出现的页面号和之后要用到的页面号的比较,找出最大下标
            max = t;//把最大下标对应的页面号与物理块中出现的相同的页面号替换掉
    }
    return max;//返回以后永不使用,或是未来在最长时间内不再被访问的页面
}
//最早在物理块memory1中出现的页面号
int Max(Pro *memory1)
{
    int max = 0;

    for(int k=1;k<m;k++)
    {
        if(memory1[k].time > memory1[max].time)
            max = k;
    }
    return max;//返回物理块等待时间最长的页面号
}

三、实验结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值