操作系统实验:页面置换算法——FIFO、LRU 代码实现

这篇具有很好参考价值的文章主要介绍了操作系统实验:页面置换算法——FIFO、LRU 代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

FIFO(First-In-First-Out)

操作系统实验:页面置换算法——FIFO、LRU 代码实现

        最简单的页面置换算法是FIFO。在分配内存页面数(AP)小于进程页面数(PP)时,最先运行的AP个页面放入内存;当内存分配页面被占满时,如果又需要处理新的页面,则将原来放的内存中的AP个页中最先进入的调出(FIFO),再将新页面放入;所使用的内存页面构成一个队列。

实验要求:

1)初始化。设置两个数组page[ap]pagecontrol[pp]分别表示进程页面数和内存分配的页面数,并产生一个随机数序列main[total_instruction](这个序列由page[ap]的下标随机构成)表示待处理的进程页面顺序,diseffect0

2)看main[]中是否有下一个元素,若有,就由main[]中获取该页面下标,并转(3),如果没有则转(7)。

3)如果该页已在内存中,就转(2),否则转(4),同时未命中的diseffect1

4)观察pagecontrol是否占满,如果占满则须将使用队列(在第(6)步中建立的)中最先进入的(就是队列的第一个单元)pagecontrol单元“清干净”,同时将page[]单元置为“不在内存中”。

5) 将该page[]pagecontrol[]建立对应关系(可以改变pagecontrol[]的标志位,也可以采用指针链接,总之至少要使对应的pagecontrol单元包含两个信息:一是它被使用了,二是哪个page[]单元使用的。page[]单元也包含两个信息:对应的pagecontrol单元号和本page[]单元已在内存中)。

 (6) 将用到的pagecontrol置入使用队列(这里的队列是一种FIFO的数据结构),返回(2)。

(7) 显示计算1-diseffect / total_instruction*100%,完成。

程序框图: 

操作系统实验:页面置换算法——FIFO、LRU 代码实现

 

代码实现: 

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

#define ProcessPageNum 10       //进程页面数
#define MemPageNum 5            //内存页面数
#define totalInstruction 100    //引用次数
int diseffect = 0;              //缺页错误数
/*定义进程页面结构体*/
struct pageNode{
    int pageID;             //进程页面ID
    int flag;               //1表示页面在内存中,0表示不在
    int pagecontrolIndex;   //所在内存页面ID 不在内存中时值为-1
};
/*定义内存页面结点*/
struct pagecontrolNode{
    int pagecontrolID;      //内存页面ID
    int flag;               //1表示被占用,0表示空闲
    int pageIndex;          //所加载进程页面ID
    struct pagecontrolNode *next;
};
/*定义FIFO队列*/
struct pagecontrolQueue{
    struct pagecontrolNode *front;
    struct pagecontrolNode *rear;
};
/*返回队首结点*/
struct pagecontrolNode* getFront(struct pagecontrolQueue *queue){
    return queue->front;
}
/*入队*/
void inQueue(struct pagecontrolQueue *queue,struct pagecontrolNode *p){
    if(queue->front == NULL){
        queue->front = p;
        queue->rear = p;
    }else{
        queue->rear->next = p;
        queue->rear = p;
        queue->rear->next = NULL;
    }
}
/*出队*/
void outQueue(struct pagecontrolQueue *queue){
    if(queue->front == NULL) exit(-1);
    else{
        queue->front = queue->front->next;
        if(queue->front == NULL) queue->rear = NULL;
    }
}
/*判断内存页面是否被占满 1为满*/
int isFull(struct pagecontrolNode *pagecontrol[MemPageNum]){
    int i = 0;
    for (i;i < MemPageNum;i++){
        if(pagecontrol[i]->flag == 0) return 0;
    }
    return 1;
}
/*初始化page数组*/
void initPage(struct pageNode *page[ProcessPageNum]){
    int i = 0;
    for(i;i < ProcessPageNum;i++){
        page[i] = (struct pageNode*)malloc(sizeof(struct pageNode)); 
        page[i]->flag = 0;
        page[i]->pageID = i;
        page[i]->pagecontrolIndex = -1;
    }
}
/*初始化pagecontrol数组*/
void initPagecontrol(struct pagecontrolNode *pagecontrol[MemPageNum]){
    int i = 0;
    for(i;i < MemPageNum;i++){
        pagecontrol[i] = (struct pagecontrolNode*)malloc(sizeof(struct pagecontrolNode)); 
        pagecontrol[i]->pagecontrolID = i;
        pagecontrol[i]->flag = 0;
        pagecontrol[i]->pageIndex = -1;
        pagecontrol[i]->next = NULL;
    }
}

int main(){
    struct pageNode *page[ProcessPageNum];
    struct pagecontrolNode *pagecontrol[MemPageNum];
    initPage(page);
    initPagecontrol(pagecontrol);
    /*初始化队列*/
    struct pagecontrolQueue *queue;
    queue = (struct pagecontrolQueue*)malloc(sizeof(struct pagecontrolQueue));
    queue->front = NULL;
    queue->rear = NULL; 
    /*构造随机序列buffer*/
    int buffer[totalInstruction];
    int i = 0;
    srand((unsigned)time(NULL));
    for(i;i < totalInstruction;i++){
        buffer[i] = rand() % ProcessPageNum;
    }
    int j = 0;
    int index = 0;  //当前内存页面下标
    for(j;j < totalInstruction;j++){
        if(page[buffer[j]]->flag == 0){ //若当前页面不在内存中
            diseffect++;                //缺页错误数加1
            page[buffer[j]]->flag = 1;
            if(isFull(pagecontrol)){    //若内存已满,则需要页面置换
                page[queue->front->pageIndex]->flag = 0;    //队首页面被换出
                page[queue->front->pageIndex]->pagecontrolIndex = -1;
                queue->front->pageIndex = page[buffer[j]]->pageID; //存入当前页面
                struct pagecontrolNode *temp;
                temp = getFront(queue);
                outQueue(queue);        //队首页面出队列
                inQueue(queue,temp);    //修改后再加入队列
            }else{                      //如果内存未满,则按照先后顺序存入
                pagecontrol[index]->flag = 1;
                pagecontrol[index]->pageIndex = page[buffer[j]]->pageID;
                page[buffer[j]]->pagecontrolIndex = pagecontrol[index]->pagecontrolID;
                inQueue(queue, pagecontrol[index]);
                index++;
            }
        }
    }
    double rightRate = (1.0 - ((double)diseffect / (double)totalInstruction))*100;
    printf("错误次数%d\n",diseffect);
    printf("正确率%.2f%%\n",rightRate);
}

LRU(Least-Recent-Used algorithm)

操作系统实验:页面置换算法——FIFO、LRU 代码实现

        计数器实现法:在最简单的情况下,为每个页表条目关联一个使用时间域,并为CPU添加一个逻辑时钟或计数器。每次内存引用都会递增时钟;且每当进行页面引用时,时钟寄存器的内容会复制到相应页面的页表条目的使用时间域。这样我们总是找到每个页面最后被引用的时间,便可以置换拥有最小使用时间的页面。

实验要求:

(1) 初始化。设置两个数组page[ap]pagecontrol[pp]分别表示进程页面数和内存分配的页面数,并产生一个随机数序列main[total_instruction](这个序列由page[ap]的下标随机构成)表示待处理的进程页面顺序,diseffect0

(2) 看序列main[]中是否有下一个元素,如果有,就由main[]中获取该页面下标,并转(3),如果没有则转(6)。

(3) 如果该page[]单元在内存中便改变页面属性,使它保留“最近使用”的信息,转(2),否则转(4),同时diseffect1

(4) 看是否有空闲页面,如果有,就返回页面指针,并转到(5),否则,在内存页面d其“清干净”,并返回该页面指针。

(5) 在需处理的page[]与(4)中得到的pagecontrol[]之间建立联系,同时让对应的page[]单元保存“最新使用”的信息,转(2)。

         (6) 如果序列处理完成,就输出计算1-diseffect / total_instruction*100%的结果

程序框图: 

操作系统实验:页面置换算法——FIFO、LRU 代码实现 

 代码实现:

#include<stdio.h>
#include<stdlib.h> 
#include<time.h>
/*实现方法与FIFO算法大同小异,无需定义队列,而是用计数器实现选择牺牲帧*/
#define ProcessPageNum 10       //进程页面数
#define MemPageNum 5            //内存页面数
#define totalInstruction 100    //引用次数
int diseffect = 0;              //缺页错误数
/*定义进程页面结构体*/
struct pageNode{
    int pageID;             //进程页面ID
    int flag;               //1表示页面在内存中,0表示不在
    int pagecontrolIndex;   //所在内存页面ID 不在内存中时值为-1
    int useTime;            //最后被引用时间
};
/*定义内存页面结点*/
struct pagecontrolNode{
    int pagecontrolID;      //内存页面ID
    int flag;               //1表示被占用,0表示空闲
    int pageIndex;          //所加载进程页面ID
};
/*初始化page数组*/
void initPage(struct pageNode *page[ProcessPageNum]){
    int i = 0;
    for(i;i < ProcessPageNum;i++){
        page[i] = (struct pageNode*)malloc(sizeof(struct pageNode)); 
        page[i]->flag = 0;
        page[i]->pageID = i;
        page[i]->pagecontrolIndex = -1;
        page[i]->useTime = 0;
    }
}
/*初始化pagecontrol数组*/
void initPagecontrol(struct pagecontrolNode *pagecontrol[MemPageNum]){
    int i = 0;
    for(i;i < MemPageNum;i++){
        pagecontrol[i] = (struct pagecontrolNode*)malloc(sizeof(struct pagecontrolNode)); 
        pagecontrol[i]->pagecontrolID = i;
        pagecontrol[i]->flag = 0;
        pagecontrol[i]->pageIndex = -1;
    }
}
/*判断内存页面是否被占满 1为满*/
int isFull(struct pagecontrolNode *pagecontrol[MemPageNum]){
    int i = 0;
    for (i;i < MemPageNum;i++){
        if(pagecontrol[i]->flag == 0) return 0;
    }
    return 1;
}
/*找到内存中页面最后引用时间最小的page结点并返回*/
struct pageNode* findMinUseTime(struct pageNode *page[ProcessPageNum]){
    struct pageNode *temp;
    temp = (struct pageNode*)malloc(sizeof(struct pageNode)); 
    temp->useTime = totalInstruction;
    int i = 0;
    for(i;i < ProcessPageNum;i++){
        if(page[i]->useTime < temp->useTime && page[i]->flag == 1){
            temp = page[i];
        }
    }
    return temp;
}
int main(){
    struct pageNode *page[ProcessPageNum];
    struct pagecontrolNode *pagecontrol[MemPageNum];
    initPage(page);
    initPagecontrol(pagecontrol);
    /*构造随机序列buffer*/
    int buffer[totalInstruction];
    int i = 0;
    srand((unsigned)time(NULL));
    for(i;i < totalInstruction;i++){
        buffer[i] = rand() % ProcessPageNum;
    }
    int j = 0;
    int timer = 0;  //设置计数器
    int index = 0;  //当前内存页面下标
    for(j;j < totalInstruction;j++){
        timer++;    //计数器递增
        page[buffer[j]]->useTime = timer;
        if(page[buffer[j]]->flag == 0){ //若当前页面不在内存中
            diseffect++;                //缺页错误数加1
            page[buffer[j]]->flag = 1;
            if(isFull(pagecontrol)){    //若内存已满
                struct pageNode *temp = findMinUseTime(page);   //找到将被置换的页面
                temp->flag = 0;
                temp->useTime = 0;
                pagecontrol[temp->pagecontrolIndex]->pageIndex = page[buffer[j]]->pageID;   //修改pagecontrol数组
                page[buffer[j]]->pagecontrolIndex = pagecontrol[temp->pagecontrolIndex]->pagecontrolID; //修改page数组
                temp->pagecontrolIndex = -1;
            }else{                      //若内存未满,则按顺序存入
                pagecontrol[index]->flag = 1;
                pagecontrol[index]->pageIndex = page[buffer[j]]->pageID;
                page[buffer[j]]->pagecontrolIndex = pagecontrol[index]->pagecontrolID;
                index++;
            }
        }
    }
    double rightRate = (1.0 - ((double)diseffect / (double)totalInstruction))*100;
    printf("错误次数%d\n",diseffect);
    printf("正确率%.2f%%\n",rightRate);
}

参考资料:

《操作系统概念(第九版)》文章来源地址https://www.toymoban.com/news/detail-473933.html

到了这里,关于操作系统实验:页面置换算法——FIFO、LRU 代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 虚拟内存页面置换算法(操作系统)

    通过这次实验,加深对虚拟内存页面置换概念的理解,进一步掌握先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的实现方法。 问题描述: 设计程序模拟先进先出FIFO、最佳置换OPI和最近最久未使用LRU页面置换算法的工作过程。假设内存中分配给每个进程的最小物

    2024年02月04日
    浏览(44)
  • 计算机操作系统——页面置换算法

    声明 :本篇博客参考书籍《计算机操作系统》(西安电子科技大学出版社) 首先说说影响页面换进换出的效率的几个因素: (1)页面置换算法。该因素是影响页面换进换出效率的重要因素。一个好的页面置换算法可以使进程在运行过程中具有较低的缺页率,从而减少页面换

    2024年02月07日
    浏览(53)
  • 操作系统:用C语言模拟先进先出的算法(FIFO)、最久未使用算法(LRU)、改进的Clock置换算法的命中率。

      通过请求页面式存储管理中页面置换算法设计,了解存储技术的特点,掌握请求页式存储管理的页面置换算法。 用程序实现生产者——消费者问题,将指令序列转换为用户虚存中的请求调用页面流。 具体要求: l页面大小为1K l用户内存容量为4页到40页 l用户外存的容量为

    2024年02月03日
    浏览(42)
  • 【操作系统】抖动、缺页中断率、页面置换算法

    对于进程P的一个长度为A的页面访问序列,如果进程P在运行中发生缺页中断的次数为F,则f = F/A称为缺页中断率。 1、进程分得的主存页框数:页框数多则缺页中断率低,页框数少则缺页中断率高。 2、页面大小:页面大则缺页中断率低,页面小则缺页中断率高。 3、页面替换

    2024年01月20日
    浏览(44)
  • 操作系统常见的十种页面置换算法

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

    2024年02月02日
    浏览(38)
  • 【操作系统】虚拟内存相关&分段分页&页面置换算法

    【进程地址空间=虚拟地址空间=C/C++程序地址空间就是那个4G的空间】 虚拟内存是操作系统内核为了对进程地址空间进行管理,而设计的一个逻辑意义上的内存空间概念。在程序运行过程中,虚拟内存中需要被访问的部分会被映射到物理内存空间中, CPU 通过将虚拟地址翻译成

    2024年02月12日
    浏览(31)
  • 页面置换算法模拟实现-操作系统课程设计基于Java

    存储管理的主要功能之一是合理的分配空间,请求页式存储管理是一种常用的虚拟存储管理技术。在地址映射过程中,若在页表中发现所要访问的页面不在内存,则产生中断,当发生中断时,系统必须在内存选择一个页面移出内存,调用页面置换算法,以便为调入新的页面让

    2024年02月07日
    浏览(33)
  • 操作系统-请求页式存储管理中常用页面置换算法模拟

    (1)先进先出调度算法(FIFO) 先进先出调度算法根据页面进入内存的时间先后选择淘汰页面,先进入内存的页面先淘汰,后进入内存的后淘汰。本算法实现时需要将页面按进入内存的时间先后组成一个队列,每次调度队首页面予以淘汰。 (2)最近最少调度算法(LRU) 先进

    2024年02月06日
    浏览(38)
  • 【操作系统--页面置换算法】C语言详解--大作业版(附代码)

    1设计和实现FIFO,LRU,OPT和CLOCK算法 2设计和实现一个完整的可供选择不同算法的程序 3通过页面访问序列随机发生器实现对上述算法的测试及性能比较 4领略页面置换背后的资源调配思想,并将其运用到其他的操作系统的知识,以及运用到生活中的资源调配策略以及解决措施 5理

    2024年02月06日
    浏览(31)
  • 【操作系统笔记04】操作系统之内存管理方式(分页、分段、段页式)、虚拟存储技术、页面置换算法

    这篇文章,主要介绍操作系统之内存管理方式(分页、分段、段页式)、虚拟存储技术、页面置换算法。 目录 一、操作系统 1.1、基地址变换机构 1.2、具有快表的地址变换机构

    2023年04月21日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包