分享好友 编程语言首页 频道列表

利用C语言实现页面置换算法的详细过程

C/C++教程  2023-02-09 05:120

操作系统实验

页面置换算法(FIFO、LRU、OPT)

概念:

1.最佳置换算法(OPT)(理想置换算法):从主存中移出永远不再需要的页面;如无这样的页面存在,则选择最长时间不需要访问的页面。于所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。

2.先进先出置换算法(FIFO):是最简单的页面置换算法。这种算法的基本思想是:当需要淘汰一个页面时,总是选择驻留主存时间最长的页面进行淘汰,即先进入主存的页面先淘汰。其理由是:最早调入主存的页面不再被使用的可能性最大。

3.最近最久未使用(LRU)算法:这种算法的基本思想是:利用局部性原理,根据一个作业在执行过程中过去的页面访问历史来推测未来的行为。它认为过去一段时间里不曾被访问过的页面,在最近的将来可能也不会再被访问。所以,这种算法的实质是:当需要淘汰一个页面时,总是选择在最近一段时间内最久不用的页面予以淘汰。

题目:

编写一个程序,实现本章所述的FIFO、LRU和最优页面置换算法。首先,生成一个随机的页面引用串,其中页码范围为0-9.将这个随机页面引用串应用到每个算法,并记录每个算法引起的缺页错误的数量。实现置换算法,一遍页面帧的数量可以从1~7。

代码

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

int numbers[20]={7,0,1,2,
                 0,3,0,4,
                 2,3,0,3,
                 2,1,2,0,
                 1,7,0,1};//本地数据,与课本一致,方便测试
int nums=0;//输入栈的个数,为了方便使用,
int stack[20][7]={10};

void begin();
void randomnum();//用于产生随机数
void init();//初始化
void FIFO();//FIFO算法
void LRU();//LRU算法
void OPT();//最优页面置换算法(OPT)
void print();//输出

int main() {
    begin();
    FIFO();
    LRU();
    OPT();
    return 0;
}
void begin()//开始菜单界面
{
    int i,j,k;
    printf("请输入页面帧的数量(1-7):");
    scanf("%d",&nums);
    for(k=0;;k++)
    {
        printf("是否使用随机数产生输入串(0:是,1:否)");
        scanf("%d",&j);
        if(j==0)
        {
            randomnum();
            break;
        }
        else if(j==1)
        {
            break;
        }
        else
        {
            printf("请输入正确的选择!\n");
        }
    }

    printf("页面引用串为:\n");
    for(i=0;i<20;i++)
    {
        printf("%d  ",numbers[i]);
    }
    printf("\n");
    init();
}
void randomnum()//如果需要使用随机数生成输入串,调用该函数
{
    srand(time(0));//设置时间种子
    for(int i = 0; i < 20; i++) {
        numbers[i] = rand() % 10;//生成区间0`9的随机页面引用串
    }
}
void init()//用于每次初始化页面栈中内容,同时方便下面输出的处理
{
    int i,j;
    for(i=0;i<20;i++)
        for(j=0;j<nums;j++)
            stack[i][j]=10;
}

void print()//输出各个算法的栈的内容
{
    int i,j;
    for(i=0;i<nums;i++)
    {
        for(j=0;j<20;j++)
        {
            if(stack[j][i]==10)
                printf("*  ");
            else
                printf("%d  ",stack[j][i]);
        }
        printf("\n");
    }

}

void FIFO()//FIFO算法
{
    init();
    int i,j=1,n=20,k,f,m;
    stack[0][0]=numbers[0];

    for(i=1;i<20;i++)
    {
        f=0;
        for(m=0;m<nums;m++)
        {
            stack[i][m]=stack[i-1][m];
        }
        for(k=0;k<nums;k++)
        {
            if(stack[i][k]==numbers[i])
            {
                n--;
                f=1;
                break;
            }
        }
        if(f==0)
        {
            stack[i][j]=numbers[i];
            j++;
        }
        if(j==nums)
            j=0;
    }
    printf("\n");
    printf("FIFO算法:\n");
    print();
    printf("缺页错误数目为:%d\n",n);
}

void LRU()//LRU算法
{
    int i,j,m,k,sum=1,f;
    int sequence[7]={0};//记录序列
    init();
    stack[0][0]=numbers[0];
    sequence[0]=nums;
    for(i=1;i<nums;i++)//前半部分,页面空置的情况
    {
        for(j=0;j<nums;j++)
        {
            stack[i][j]=stack[i-1][j];
        }

        for(j=0;j<nums;j++)  //判断要插入的是否在栈中已经存在
        {
            f=0;
            if(stack[i][j]==numbers[i])
            {
                f=1;
                sum--;
                sequence[j]=nums;
                break;
            }
        }

        for(j=0;j<nums;j++)
        {
            if(sequence[j]==0&&f==0)
            {
                stack[i][j]=numbers[i];
                sequence[i]=nums;//最近使用的优先级列为最高
                break;
            }
        }
        for(j=0;j<i;j++)//将之前的优先级序列都减1
        {
            if(sequence[j]!=0)
               sequence[j]--;
        }
        //sequence[i]=nums;
        sum++;
    }

    for(i=nums;i<20;i++)//页面不空,需要替换的情况
    {
        int f;
        f=0;
        for(j=0;j<nums;j++)
        {
            stack[i][j]=stack[i-1][j];
        }
        for(j=0;j<nums;j++)//判断输入串中的数字,是否已经在栈中
        {
            if(stack[i][j]==numbers[i])
            {
                f=1;
                k=j;
                break;
            }
        }
        if(f==0)//如果页面栈中没有,不相同
        {
            for(j=0;j<nums;j++)//找优先序列中为0的
            {
                if(sequence[j]==0)
                {
                    m=j;
                    break;
                }
            }
            for(j=0;j<nums;j++)
            {
                sequence[j]--;
            }
            sequence[m]=nums-1;
            stack[i][m]=numbers[i];
            sum++;
        }
        else//如果页面栈中有,替换优先级
        {
           if(sequence[k]==0)//优先级为最小优先序列的
           {
               for(j=0;j<nums;j++)
               {
                   sequence[j]--;
               }
               sequence[k]=nums-1;
           }
           else if(sequence[k]==nums-1)//优先级为最大优先序列的
           {
               //无需操作
           }
           else//优先级为中间优先序列的
           {
               for(j=0;j<nums;j++)
               {
                   if(sequence[k]<sequence[j])
                   {
                       sequence[j]--;
                   }
               }
               sequence[k]=nums-1;
           }
        }
    }
    printf("\n");
    printf("LRU算法:\n");
    print();
    printf("缺页错误数目为:%d\n",sum);
}

void OPT()//OPT算法
{
    int i,j,k,sum=1,f,q,max;
    int seq[7]={0};//记录序列
    init();
    stack[0][0]=numbers[0];
    seq[0]=nums-1;

    for(i=1;i<nums;i++)//前半部分,页面空置的情况
    {
        for(j=0;j<nums;j++)
        {
            stack[i][j]=stack[i-1][j];
        }

        for(j=0;j<nums;j++)  //判断要插入的是否在栈中已经存在
        {
            f=0;
            if(stack[i][j]==numbers[i])
            {
                f=1;
                sum--;
                //b++;
                seq[j]=nums;
                break;
            }
        }

        for(j=0;j<nums;j++)
        {
            if(seq[j]==0&&f==0)
            {
                stack[i][j]=numbers[i];
                seq[j]=nums;//最近使用的优先级列为最高
                break;
            }
//            else if(seq[j]==0&&f==1){
//                b++;
//                sum--;
//                seq[j]=nums-1;
//                break;
//            }
        }
        for(j=0;j<nums;j++)//将之前的优先级序列都减1
        {
            if(seq[j]!=0)
               seq[j]--;
        }

        sum++;
    }
    for(i=nums;i<20;i++)//后半部分,页面栈中没有空的时候情况
    {
        //k=nums-1;//最近的数字的优先级
        for(j=0;j<nums;j++)//前面的页面中内容赋值到新的新的页面中
        {
            stack[i][j]=stack[i-1][j];
        }
        for(j=0;j<nums;j++)
        {
            f=0;
            if(stack[i][j]==numbers[i])
            {
                f=1;
                break;
            }
        }
        if(f==0)//页面中没有,需要替换的情况
        {
            for(q=0;q<nums;q++)//优先级序列中最大的就是最久不会用的,有可能出现后面没有在用过的情况
            {
                seq[q]=20;
            }
            for(j=0;j<nums;j++)//寻找新的优先级
            {
                for(q=i+1;q<20;q++)
                {
                    if(stack[i][j]==numbers[q])
                    {
                        seq[j]=q-i;
                        break;
                    }
                }
            }
            max=seq[0];
            k=0;
            for(q=0;q<nums;q++)
            {
                if(seq[q]>max)
                {
                    max=seq[q];
                    k=q;
                }
            }
            stack[i][k]=numbers[i];
            sum++;
        }
        else
        {
            //页面栈中有需要插入的数字,无需变化,替换的优先级也不需要变化
        }
    }
    printf("\n");
    printf("OPT算法:\n");
    print();
    printf("缺页错误数目为:%d\n",sum);
}

运行结果截图:

利用C语言实现页面置换算法的详细过程

利用C语言实现页面置换算法的详细过程

利用C语言实现页面置换算法的详细过程

总结

设置多个数组,一个用来模仿栈,一个用来存要存取的页面,还有在OPT算法和LRU算法中,记录栈中每个数据的替换优先级。
之前的代码写的有点烂,重新看了一次才感觉之前的有多烂,哈哈哈哈哈,这个代码能在linux上跑通的,在windows上肯定也没得问题

原文地址:https://blog.csdn.net/braylon_zhang/article/details/111157443

查看更多关于【C/C++教程】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
Rust应用调用C语言动态库的操作方法
目录外部功能接口FFIUDP套接字的读超时Rust调用C语言动态库中的函数避免重复造***,使用Rust官方C语言库外部功能接口FFI虽然高级(脚本)编程语言的功能丰富,表达能力强,但对底层的一些特殊操作的支持并不完善,就需要以其他编程语言来实现。调用其他编程语

0评论2023-02-09585

Delphi中获取Unix时间戳及注意事项(c语言中time()是按格林威治时间计算的,比北京时间多了8小时)
uses DateUtils;DateTimeToUnix(Now) 可以转换到unix时间,但是注意的是,它得到的时间比c语言中time()得到的时间大了8*60*60这是因为Now是当前时区的时间,c语言中time()是按格林威治时间计算的,北京时间比格林威治时间多了8小时DateTimeToUnix(Now)-8*60*

0评论2023-02-09876

Unicode与UTF-8互转(c语言和lua语言) python utf-8转unicode
1. 基础1.1 ASCII码我们知道, 在计算机内部, 全部的信息终于都表示为一个二进制的字符串. 每个二进制位(bit)有0和1两种状态, 因此八个二进制位就能够组合出 256种状态, 这被称为一个字节(byte). 也就是说, 一个字节一共能够用来表示256种不同的状态, 每个状态

0评论2023-02-09468

R语言之merge详解 c语言merge函数代码
merge是R语言中用来合并数据框的函数merge函数的声明:?1234merge(x, y, by = intersect(names(x), names(y)),      by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,      sort = TRUE, suffixes = c(".x"

0评论2023-02-09489

R语言调用的C语言源代码查询 R语言 c
R语言使用时可以调用自己写的C代码,但是有些C函数是软件包自带的,怎么查询在使用软件包 kerfdr 时,涉及到一个函数y = .C("massdist", x = as.double(xtrunc), xmass = as.double(tau[trunc]/sum(tau[trunc])), nx = nx, xlo = as.double(lo), xhi = as.dou

0评论2023-02-09487

centos安装与配置R语言 centos配置c语言环境
Linux下安装R语言一、编译安装      由于采用编译安装,所以需要用到gcc编译环境,在编译前check文件时还会用到libXt-devel和readline-devel两个依赖,所以在编译R语言源码时先将这些工具和依赖包准备好。readline-devel 也可以不安装,不安装此包R语言编

0评论2023-02-09905

C语言利用链表实现学生成绩管理系统
链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表都有一个头指针,一般以head来表示

0评论2023-02-09722

C语言通过三种方法实现属于你的通讯录
目录一、基础版本1.1 通讯录的个人信息(结构体来实现)1.2通讯录名单1.3人员初始化1.4菜单1.5主函数二、功能的实现2.1、增加人数2.2、删除人数2.3、查找2.4、展示2.5、排序(这里我是通过名字)三、通讯录进阶(设置动态存储)3.1通讯录从静态改为动态3.2通

0评论2023-02-09881

C++集体数据交换实现示例讲解 c语言两个数据交换
目录一、说明二、示例和代码一、说明到目前为止介绍的功能共享一对一的关系:即一个进程发送和一个进程接收。链接是通过标签建立的。本节介绍在多个进程中调用相同参数但执行不同操作的函数。对于一个进程,函数可能会发送数据,对于另一个进程,它可能会接收

0评论2023-02-09687

C语言中#if的使用 c语言中%c
目录#if定义#if使用#if的后面接的是表达式#if defined的使用ifdef的使用结尾#if定义#if和#endif是一组同时使用的,叫做条件编译指令。#if与#define、#include等指令一样是由预处理器这个强大的工具处理的,预处理器可以在编译前处理c程序。#if使用#if的后面接

0评论2023-02-09343

更多推荐