使用C++STL中的deque实现操作系统FIFO、LRU页面置换算法

本文通过一个具体的示例程序介绍了FIFO(先进先出)和LRU(最近最少使用)两种页面置换算法的实现,并对它们在相同条件下的表现进行了比较。详细展示了如何使用C++中的双端队列来模拟这两种算法,并计算了各自的缺页率和命中率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <deque>//双端队列所在的头文件
#include <algorithm>//find()函数所在的头文件
using namespace std;
const int LEN = 17;
deque<int> fifo;
deque<int> lru;
int main()
{
    int pages[] = {1,2,5,7,5,7,1,4,3,5,6,4,3,2,1,5,2};//页面走向
    int success = 0;//命中的次数
    int fail = 0;//缺页次数
    //FIFO算法
    for(int i = 0;i < LEN;i++){
        //查找物理块中是否已经存在要访问的页面
        auto pos=find(fifo.cbegin(),fifo.cend(),pages[i]);
        [//auto关键字详解](http://blog.youkuaiyun.com/liuweiyuxiang/article/details/51534)
        if( pos != fifo.cend()){
            //cout<<"找到了元素 "<<pages[i]<<endl;
            success++;
        }else{
            //cout<<"未找到元素 "<<pages[i]<<endl;
            fail++;
            if(fifo.size() < 4){//分配4个物理块
                fifo.push_back(pages[i]);
            }else{
                fifo.pop_front();
                fifo.push_back(pages[i]);
            }
        }
    }
    cout<<"使用FIFO算法,分配4个内存块时:"<<endl;
    cout<<"\t缺页率为:"<<(double)fail/(fail+success)<<endl;
    cout<<"\t命中率为:"<<(double)success/(fail+success)<<endl;
    /*使用LRU算法(使用双端队列实现P165特殊的栈。该栈的栈顶元素始终为最近访问的元素,
    这样栈底元素即为最久未使用的元素,当物理块用尽时将栈底元素换出即可)*/
    success = 0;
    fail = 0;
    for(int i = 0;i < LEN;i++){
        auto pos = find(lru.cbegin(),lru.cend(),pages[i]);
        if( pos != lru.cend()){
            //cout<<"找到了元素 "<<pages[i]<<endl;
            success++;
            lru.erase(pos);//删除指定位置的元素
            lru.push_back(pages[i]);//将该元素重新加入到队列尾
        }else{
             //cout<<"未找到元素 "<<pages[i]<<endl;
            fail++;
            if(lru.size() < 4){//分配4个物理块
                lru.push_back(pages[i]);//物理块未满将该元素重新加入到队列尾
            }else{
                lru.pop_front();//物理块已满将队首部元素删除
                lru.push_back(pages[i]);//将新进的元素添加到队列尾
            }
        }
    }
    cout<<"使用LRU算法,分配4个内存块时:"<<endl;
    cout<<"\t缺页率为:"<<(double)fail/(fail+success)<<endl;
    cout<<"\t命中率为:"<<(double)success/(fail+success)<<endl;
    return 0;
}

小结:


1.双端队列常用函数
【头文件】#include<deque>
【函数构造】
deque c 创建一个空的deque。
deque c1(c2) 复制一个deque。
deque c(n) 创建一个deque,含有n个数据,数据均已缺省构造产生。
deque c(n, elem) 创建一个含有n个elem拷贝的deque
deque c(beg,end) 创建一个以[beg;end)区间的deque
c.~deque() 销毁所有数据,释放内存
【成员函数】:
c.assign(beg,end) 将[beg; end)区间中的数据赋值给c。
c.assign(n,elem) 将n个elem的拷贝赋值给c。
c. at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。
c.back() 传回最后一个数据,不检查这个数据是否存在。
c.begin() 传回迭代器中的第一个数据。
c.clear() 移除容器中所有数据。
c.empty() 判断容器是否为空。
c.end() 指向迭代器中的最后一个数据地址。
c.erase(pos) 删除pos位置的数据,传回下一个数据的位置。
c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。
c.front() 传回第一个数据。
get_allocator 使用构造函数返回一个拷贝。
c.insert(pos,elem) 在pos位置插入一个elem拷贝,传回新数据位置
c.insert(pos,n,elem) 在pos位置插入>n个elem数据。无返回值
c.insert(pos,beg,end) 在pos位置插入在[beg,end)区间的数据。无返回值
c.max_size() 返回容器中最大数据的数量。
c.pop_back() 删除最后一个数据。
c.pop_front() 删除头部数据。
c.push_back(elem) 在尾部加入一个数据。
c.push_front(elem) 在头部插入一个数据。
c.rbegin() 传回一个逆向队列的第一个数据。
c.rend() 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) 重新指定队列的长度。
c.size() 返回容器中实际数据的个数。
c.swap(c2) 将c1和c2元素互换。
swap(c1,c2) 将c1和c2元素互换。
【特点】
1、支持随机访问,即支持[]以及at(),但是性能没有vector好。
2、支持两端操作,push(pop)-back(front),但性能不及list。
【最佳使用情况】
1、需要在两端插入和删除元素。
2、无需引用容器内的元素。
3、要求容器释放不再使用的元素。
2.查找某个元素是否在双端队列中
【头文件】

            include <algorithm>

【find()函数】

        deque<int> lru={1,2,3};
        auto pos = find(lru.cbegin(),lru.cend(),num);
时钟算法 页面置换算法 #pragma once #include <iostream> #include "Pclass.h" using namespace std; class Allocation { private: int pnum;//页面数 int bnum;//分配块数 //int ID; int num;//访问页面次数 Pclass * block;//块数组 int *page;//页访问顺序 //int p; public: Allocation(int pn,int bl,int n) { pnum=pn; bnum=bl; num=n; //ID=id; block=new Pclass [bnum]; page=new int [num]; cout<<"页面访问顺序:"; for(int i=0;i<num;i++) { page[i]=rand()%pnum+1; cout<<page[i]<<" "; } cout<<endl; //p=0; } void FIFO() { cout<<"先进先出算法:"<<endl; int p=0; int nm=0; for(int i=0;i<num;i++) { if(Haven(page[i])!=(-1)) { nm++; } else { block[p].num=page[i]; p=(++p)%bnum; } for(int j=0;j<bnum;j++) { if(block[j].num!=0) { cout<<block[j].num<<" "; } } cout<<endl; } cout<<"命中率为:"<<(double)nm/(double)num<<endl; } int Haven(int n) { for(int i=0;i<bnum;i++) { if(block[i].num==n) { return i; } } return -1; } void LRU() { int p=0; int nm=0; for(int i=0;i<bnum;i++) { block[i].num=0; block[i].visited=false; } for(int i=0;i<num;i++) { int temp=Haven(page[i]); if(temp!=(-1)) { block[temp].visited=true; nm++; } else { //int j=0; while(1) { if(block[p].visited==false) { block[p].num=page[i]; p=(++p)%bnum; break; } else { block[p].visited=false; p=(++p)%bnum; } } } for(int j=0;j<bnum;j++) { if(block[j].num!=0) { cout<<block[j].num<<" "; } } cout<<endl; } cout<<"命中率为:"<<(double)nm/(double)num<<endl; } void SLRU() { int p=0; int nm=0; for(int i=0;i<bnum;i++) { block[i].num=0; block[i].visited=false; } for(int i=0;i<num;i++) { int temp=Haven(page[i]); if(temp!=(-1)) { block[temp].visited=true; nm++; } else { for(int j=0;j<bnum;j++) { if(block[p].visited==false&&block[p].changed==false) { block[p].num=page[i]; if(rand()%2) { block[p].changed=true; } p=(++p)%bnum; goto over; } else { block[p].visited=false; p=(++p)%bnum; } } while(1) { if(block[p].changed==false) { block[p].num=page[i]; p=(++p)%bnum; break; } else { block[p].changed=false; p=(++p)%bnum; } } } over: for(int j=0;j<bnum;j++) { if(block[j].num!=0) { cout<<block[j].num<<" "; } } cout<<endl; } cout<<"命中率为:"<<(double)nm/(double)num<<endl; } ~Allocation(void) { } };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值