操作系统(4)页面替换策略算法模拟实现

news2024/11/19 7:34:45

1. 效果展示

2. 程序流程图

(1) 程序总流程

(2) FIFO策略

(3) LRU策略

  

(4) OPT策略

3. 数据结构设计

//页面数据结构
    struct PageInfo {
        int id;
        int visit;
    };

    PageInfo* Block;  // 物理块
    PageInfo* Page;  // 页面

4. 功能函数设计

序号

函数

功能说明

1

void init();

从data.txt文件中读取数据进行初始化

2

int findSpace();

查找是否有空闲物理块

3

int findExist(int curren);

查找物理块中是否存在该页面

4

int findReplace();

查找应予以置换的页面

5

int showSingle(int curren);

打印每一个序列号的结果

6

void FIFO();

替换最早进入的页面

7

void LRU();

淘汰上次使用距当前最远的页面

8

void OPT();

淘汰下一次访问距当前最远的页面中序号最小的一页

9

int main();

主函数,控制程序的整个流程

5. 代码实现

/// 页面替换策略 FIFO、OPT、LRU
#include <bits/stdc++.h>
using namespace std;

class Pager {
public:
    //页面数据结构
    struct PageInfo {
        int id;
        int visit;
    };

    PageInfo* Block;  // 物理块
    PageInfo* Page;  // 页面

    int BlockNum;
    int PageNum;

    int LockPageCnt;  //缺页次数
    int ChangePageCnt;  //置换次数

public:
    /// 从data.txt文件中读取数据,并初始化
    void init() {
        cout<<"正在进行数据读取..."<<endl;
        ifstream readData;
        readData.open("data.txt");

        readData>>BlockNum;
        Block = new PageInfo[BlockNum];
        for (int i = 0; i < BlockNum; ++i) {
            Block[i].id = -1;
            Block[i].visit = 0;
        }
        readData>>PageNum;
        Page = new PageInfo[PageNum];
        for (int i = 0; i < PageNum; ++i) {
            readData>>Page[i].id;
            Page[i].visit = 0;
        }
        readData.close();

        cout<<"数据读取结果如下:"<<endl;
        printf("物理块数为:%d\n", BlockNum);
        printf("页面个数为:%d\n", PageNum);
        cout<<"页面序列如下:"<<endl;
        for (int i = 0; i < PageNum; ++i) {
            printf("%d  ", Page[i].id);
        }
        cout<<endl;
        cout<<"数据读取完毕!"<<endl;
    }

    /// 查找是否有空闲块
    int findSpace() {
        for (int i = 0; i < BlockNum; ++i) {
            if (Block[i].id == -1) {
                return i;
            }
        }
        return -1;
    }

    /// 查找内存中是否存在该页面
    int findExist(int curren) {
        for (int i = 0; i < BlockNum; ++i) {
            if(Block[i].id != -1 && Block[i].id == curren) {
                return i;
            }
        }
        return -1;
    }

    /// 查找应予以置换的页面
    int findReplace() {
        int pos = 0;
        for (int i = 1; i < BlockNum; i++) {
            if(Block[i].id != -1 && Block[i].visit > Block[pos].visit) {
                pos = i;
            }
        }
        return pos;
    }

    /// 显示置换一次后的Block
    void showSingle(int curren) {
        printf("%d : ", curren);
        for (int i = 0; i < BlockNum; ++i) {
            if(Block[i].id != -1) {
                printf(" %d ", Block[i].id);
            }
        }
        cout<<endl;
    }

    /// FIFO
    void FIFO() {
        int exist, space, position;
        double fifo_missRate;
        LockPageCnt = 0;
        ChangePageCnt = 0;
        printf("\n----FIFO策略-start----\n");
        for (int i = 0; i < PageNum; ++i) {
            exist = findExist(Page[i].id);
            // 当前页面号不在内存中
            if (exist == -1) {
                LockPageCnt++;
                space = findSpace();
                // 当前内存已满,需置换
                if(space == -1) {
                    ChangePageCnt++;
                    position = findReplace();
                    Block[position] = Page[i];
                }
                // 当前内存未满,直接加入
                else {
                    Block[space] = Page[i];
                }

            }

            showSingle(Page[i].id);

            for (int j = 0; j < BlockNum; ++j) {
                if (Block[j].id != -1) {
                    Block[j].visit++;  // Block中的页面停留时间+1
                }
            }
        }
        fifo_missRate = (double) LockPageCnt / PageNum;
        printf("缺页次数:%d\n", LockPageCnt);
        printf("置换次数:%d\n", ChangePageCnt);
        printf("FIFO缺页率:%lf%%\n", fifo_missRate*100);
        printf("----FIFO策略-end----\n");
    }

    /// OPT
    void OPT() {
        int exist, space, position;
        double opt_missRate;
        LockPageCnt = 0;
        ChangePageCnt = 0;
        printf("\n----OPT策略-start----\n");
        for (int i = 0; i < PageNum; ++i) {
            exist = findExist(Page[i].id);
            // 当前页面号不在内存中
            if (exist == -1) {
                LockPageCnt++;
                space = findSpace();
                // 当前内存已满,需置换
                if(space == -1) {
                    ChangePageCnt++;
                    for (int k = 0; k < BlockNum; k++) {
                        for (int j = i+1; j < PageNum; j++) {
                            if (Block[k].id != Page[j].id) {
                                Block[k].visit = 1000;
                            } else {
                                Block[k].visit = j-i;
                                break;
                            }
                        }
                    }
                    position = findReplace();
                    Block[position] = Page[i];
                }
                // 当前内存未满,直接加入
                else {
                    Block[space] = Page[i];
                }
            }
            showSingle(Page[i].id);
        }
        opt_missRate = (double) LockPageCnt / PageNum;
        printf("缺页次数:%d\n", LockPageCnt);
        printf("置换次数:%d\n", ChangePageCnt);
        printf("OPT缺页率:%lf%%\n", opt_missRate*100);
        printf("----OPT策略-end----\n");
    }

    /// LRU
    void LRU() {
        int exist, space, position;
        double lru_missRate;
        LockPageCnt = 0;
        ChangePageCnt = 0;
        printf("\n----LRU策略-start----\n");
        for (int i = 0; i < PageNum; ++i) {
            exist = findExist(Page[i].id);
            // 当前页面号不在内存中
            if (exist == -1) {
                LockPageCnt++;
                space = findSpace();
                // 当前内存已满,需置换
                if(space == -1) {
                    ChangePageCnt++;
                    position = findReplace();
                    Block[position] = Page[i];
                }
                    // 当前内存未满,直接加入
                else {
                    Block[space] = Page[i];
                }
            }
            // 当前页面在内存中
            else {
                Block[exist].visit = 0;
            }
            showSingle(Page[i].id);

            for (int j = 0; j < BlockNum; ++j) {
                if (Block[j].id != -1) {
                    Block[j].visit++;  // Block中的页面停留时间+1
                }
            }
        }
        lru_missRate = (double) LockPageCnt / PageNum;
        printf("缺页次数:%d\n", LockPageCnt);
        printf("置换次数:%d\n", ChangePageCnt);
        printf("LRU缺页率:%lf%%\n", lru_missRate*100);
        printf("----LRU策略-end----\n");
    }
};

int main() {
    Pager page;
    int chooseAlgorithm;
    while(true)
    {
        printf("\t-------------------------------------\n");
        printf("\t||                                  ||\n");
        printf("\t||       页面替换策略模拟程序           ||\n");
        printf("\t||           1. FIFO                ||\n");
        printf("\t||           2. LRU                 ||\n");
        printf("\t||           3. OPT                 ||\n");
        printf("\t||           0. 退出程序             ||\n");
        printf("\t||                                  ||\n");
        printf("\t-------------------------------------\n");

        printf("请输入序号进行选择:");
        cin>>chooseAlgorithm;
        switch(chooseAlgorithm)
        {
            case 1:
                page.init();
                page.FIFO();
                break;
            case 2:
                page.init();
                page.LRU();
                break;
            case 3:
                page.init();
                page.OPT();
                break;
            case 0:
                cout<<"正在退出程序..."<<endl;
                system("pause");
                return 0;
            default:
                cout<<"请输入正确的序号进行选择!"<<endl;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

我国电力物流行业发展现存问题及解决策略分析 企业应加强信息化建设

电力物流是电力发、输、配、售流程的一部分&#xff0c;是为了满足终端用户需求&#xff0c;对电力从发电到终端用户的高效率、高效益的流动以及流程各环节相互提供的服务和相关信息在此过程中的正、反向流动所进行的计划、实施与控制过程。 根据观研报告网发布的《中国电力物流…

nginx反向代理ssl配置

nginx反向代理是各大应用环境最重要的环节&#xff0c;今天我们来说说如何配置反代理SSL这书&#xff0c;首先配置准备好&#xff1a;nginx环境、SSL证书、确定需要设置的端口防火墙开放&#xff08;尤其是云服务器需要单独设置&#xff0c;windows防火墙单独设置&#xff09;。…

电巢:上海半导体投资浪潮的前奏、高潮与转折

朱旭东是上海半导体投资界的开创性人物&#xff0c;他带领浦科投资投出了中微半导体、盛美半导体等当下的「国之重器」&#xff0c;并控股了万业企业、上工申贝等A股上市公司。随后又在国内率先发起设立并管理了上海半导体装备材料产业投资基金&#xff0c;推动旗下上市公司万业…

前端开发--JavaScript Bom和Dom

JavaScript Bom和Dom这一篇就够啦JavaScript Bom和Dom1、Web API 基本认知2、DOM -- 基础2.1 DOM简介2.2 获取元素2.3 事件基础2.4 操作元素2.5 节点操作2.6 DOM重点核心3、DOM -- 事件高级3.1 注册事件(绑定事件)3.2 删除事件(解绑事件)3.3 DOM事件流3.4 事件对象3.5 事件委托…

如何理解UML2.5.1(05篇)

标记subsets和redefines可以说是UML2.5.1中最重要的一对标记。标记subsets相对要好理解一些&#xff0c;但是redefines的含义就没有那么直白。先看一下目前已知的subsets和redefines的效果&#xff1a; 假定图一中A1和B1的关联两端的标记都是subsets&#xff0…

Torch计算方法

Torch 中的计算方法与 Numpy 的计算方法很类似&#xff1b;Torch中带 “下划线 ” 的操作&#xff0c;都是in-place的。 求和&#xff1a; torch.sum() 对输入的 tensor 数据的某一维度求和&#xff1b; &#xff11;&#xff0e;torch.sum(input, dtypeNone) &#xff12;&…

硬盘 / 硬盘控制器主要端口寄存器 / Controller Register

文章目录IDE 与 SATA硬盘分区表结构硬盘控制器主要端口寄存器data 寄存器Error && FeaturesErrorFeaturesSector countLBA low | mid | highdevice 寄存器StatusCommandIDE 与 SATA 很久以前&#xff0c;硬盘控制器和硬盘是分开的&#xff0c;后面开发了一个新接口&am…

【观察】新华三:智慧计算“再进化”,算力创新“再升级”

今天&#xff0c;算力就是生产力已成为业界共识&#xff0c;特别是算力作为数字经济时代的关键生产力要素&#xff0c;更成为了挖掘数据要素价值&#xff0c;推动数字经济发展的核心支撑力和驱动力。在此过程中&#xff0c;由算力驱动的数字经济除了以信息产业这一独立的经济形…

Linux进程间通信(二):命名管道的使用和原理

文章目录一、前言二、命名管道的使用一、前言 我们上篇博客里谈到&#xff0c;进程间通信的本质在于如何让两个进程看到同一份资源。匿名管道的核心思想就是让子进程继承父进程&#xff0c;从而让父子进程看到同一份管道文件&#xff0c;但这也使通信仅仅局限在具有血缘关系的进…

比Sqoop功能更加强大开源数据同步工具DataX实战

文章目录概述定义与Sqoop对比框架设计支持插件核心架构核心优势部署基础环境安装从stream读取数据并打印到控制台读取MySQL写入HDFS读取HDFS写入MySQL执行流程概述 定义 DataX 官网地址 https://maxwells-daemon.io/ DataX GitHub源码地址 https://github.com/alibaba/DataX D…

SaaS是什么?企业采购SaaS有什么好处?

简单的来讲讲我们对SaaS的理解吧。过去通常来说&#xff0c;我们采购企业使用的产品&#xff0c;通常有比如传统的软件包下载、按照自己的需求找开发商定制、如果有自研能力的团队可以自己去开发。但是这样就比如带来很多问题&#xff1a; 比如业务规则更新了怎么办&#xff1…

Protobuf 了解

Protocol Buffers 是一种结构数据序列化方法&#xff0c;可以将C中定义的存储类的内容与二进制序列串相互转换&#xff0c;主要用于数据传输或数据存储&#xff0c;可类比XML、JSON&#xff0c;而XML、JSON基于文本格式&#xff0c;protobuf是二进制格式&#xff0c;所以比XML、…

【论文阅读总结】inception v4与Inception-ResNet总结

Inception-v4, Inception-ResNet和Residual connections对学习的影响1.摘要2.引言3.文献综述4.体系结构的选择4.1 Pure Inception4.2 Residual Inception Blocks【残差Inception 块】4.3 Scaling of the Residuals【残差的缩放】4.3.1实验发现4.3.1.1实验发现14.3.1.2实验发现2…

ERP容灾备份维护工作有哪些?服务器容灾备份

ERP维护工作有哪些&#xff1f;这是公司信息化专员工作职责&#xff1a;信息规划  1、参与 公司信息化系统总体构架&#xff0c;建立健全公司信息化各项管理制度和标准业务流程&#xff0c;组织公司各业务部门不断进行业务流程的梳理、优化和创新&#xff0c;推动信息化的持续…

408 考研《操作系统》第三章第二节:内存管理、覆盖和交换 、连续分配管理方式、动态分区分配算法

文章目录1. 内存管理的概念1.1 内存保护1.2 总结2. 覆盖与交换2.1 覆盖技术2.2 交换技术2.3 总结&#xff1a;3. 连续分配管理方式3.1 单一连续分配3.2 固定分区分配3.3 动态分区分配3.4 总结4. 动态分区分配算法4.1 首次适应算法4.2 最佳适应算法4.3 最坏适应算法4.4 邻近适应…

米尔基于ARM架构核心板的国产化EtherCAT主站控制器解决方案

EtherCAT是由德国BECKHOFF自动化公司于2003年提出的实时工业以太网技术。它具有高速和高数据有效率的特点&#xff0c;支持多种设备连接拓扑结构。其从站节点使用专用的控制芯片&#xff0c;主站使用标准的以太网控制器。 EtherCAT是一种工业以太网技术&#xff0c;看到的大多…

【RocketMQ】RocketMQ实例--顺序消息

1、应用场景 一、以证券股票交易撮合场景为例&#xff0c;对于出价相同的交易单&#xff0c;坚持按照先出价先交易的原则&#xff0c;下游处理订单的系统需要严格按照出价顺序来处理订单。 二、以数据库变更增量同步场景为例&#xff0c;上游源端数据库按需执行增删改操作&…

RK3568烧录系统

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、烧录工具二、烧录步骤单独烧录烧录整个固件总结前言 前面我们已经学会了编译系统&#xff0c;包括一键编译和单独编译&#xff0c;其中单独编译适合我们做驱…

ENSP 路由器到本地(现实)PC的FTP实验

前言&#xff1a; 在一个风和日丽的下午&#xff0c;我同事突然问我ENSP和本地PC怎么上传和下载文件&#xff1f;我本以为这个很简单&#xff0c;然后我开始了面向百度编程&#xff0c;但是网上的大多数都是ENSP里面的路由器、服务器和PC间的FTP实验&#xff0c;而不是到本地&…

嵌入式经典通信总线协议:SPI协议

目录 一、spi简介 二、SPI特性 三、spi四种工作方式 四、实现代码 1.选择开发板 2.选择SPI 3.设置硬件片选使能和通讯方式&#xff0c;其他根据需要选择 4. 生成代码 一、spi简介 SPI 是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口…