页面置换算法

#include <iostream>
#define M 3
#define N 20

using namespace std;

struct block
{
    int iPageNum;      //物理块里存储的页面号
    int iBlockFlag;		//在三种算法中用到的标记。例如在FIFO中为在内存中的时间
};
//算法模拟移位寄存器原理

void FIFO(int iTempPage[N],int flag[N],block myBlock[M]);
void Optimal(int iTempPage[N],int flag[N],block myBlock[M]);
void LRU(int iTempPage[N],int flag[N],block myBlock[M]);
int PageNum(const int array[]);

int main()
{
    block myBlock[M];       // 定义三个物理块
    int iPageString[N]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};    //页面引用串

    int iTempPage[N]; //临时页面引用串
    int flag[N];      //缺页标记;1为缺页,0为不缺页,在统计缺页次数时用

    int i;

    bool bExitFlag=true;   //退出标记
    char ch;		  //接收选择算法时传进来的值

    while(bExitFlag)
    {
        cout<<"\n"<<"请选择页面置换算法:\n";
        cout<<"f:FIFO置换算法\to:OPT置换算法\tl:LRU置换算法\tx:退出置换算法程序.\n";
        cin>>ch;

        //初始化数据
        // 当选择一中置换算法后,将临时页面申请串进行初始化,并且标记全部置为0
        if((ch=='f')||(ch=='o')||(ch=='l'))
        {
            for(i=0;i<N;i++)
            {
                iTempPage[i]=iPageString[i];  //初始化临时页面引用串
                flag[i]=0;                    //初始化缺页标记为0,即不缺页
            }
        }

        switch(ch)
        {
            case 'f':
                cout<<"FIFO置换算法的结果是:\n";
                FIFO(iTempPage,flag,myBlock);
                //用PageNum(flag)统计缺页次数
                cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
                break;
            case 'o':
                cout<<"OPT置换算法的结果是:\n";
                Optimal(iTempPage,flag,myBlock);
                cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
                break;
            case 'l':
                cout<<"LRU置换算法的结果是:\n";
                LRU(iTempPage,flag,myBlock);
                cout<<"\n缺页次数为"<<PageNum(flag)<<endl;
                break;
            case 'x':
                cout<<"退出置换算法。\n";
                bExitFlag=false;
                break;
            default:
                cout<<"输入有误,请重新选择置换算法:\n";
        }
    }
    return 0;
}

//对数组中的数累加
int PageNum(const int array[])
{
    int num=0;
    for(int j=0;j<N;j++)
        num=num+array[j];
    return num;
}

//定位函数,在最佳算法中用于定位;
//定位物理块中的某一个页面在引用串中还未访问串中页面的位置
int allocate(int iPage,int iLoc,const int iTempPage[N])
{
    int i;
    for(i=iLoc;i<N;i++)
    {
        if (iPage==iTempPage[i])
            return i;
    }
    //永远不再访问的页面位置假定为N
    return N;
}

//找数组中最大值所在的下标,返回最大值在数组中的位置(下标)
int max(block array[M])
{
    int j,loc;
    int temp=array[0].iBlockFlag;
    loc=0;

    for(j=1;j<M;j++)
    {
        if (temp<array[j].iBlockFlag)
        {
            temp=array[j].iBlockFlag;
            loc=j;
        }
    }
    return loc;
}

//输出剩余的数据
//loc为页面引用串中
void output(int iPage,int flag,block myBlock[M],int blockNum)
{
    int j;
    //如果缺页则输出缺页标志,否则不输出
    if (flag==1)
        cout<<"\n  "<<flag;
    else
        cout<<"\n  ";
    cout<<"\t  "<<iPage;
    for(j=0;j<blockNum;j++)
        cout<<"\t  "<<myBlock[j].iPageNum;
}

//初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
//同时将目前物理块中的内容输出
void InitialBlock(int iTempPage[N],int flag[N],block myBlock[M])
{
    int i;
    for(i=0;i<M;i++)
    {
        //初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
        myBlock[i].iPageNum=iTempPage[i];
        //myBlock[i].iBlockFlag的值:0为最后进来的,数越大表示进来的越早
        //在最佳置换算法中则初始化此值没有意义
        myBlock[i].iBlockFlag=(M-1)-i;
        flag[i]=1;   //此时为缺页
    }
    //输出
    cout<<"\n缺页\t引用串\t物理块1\t物理块2\t物理块3";
    for(i=0;i<M;i++)
        output(iTempPage[i],flag[i],myBlock,i+1);
}

//FIFO置换算法
void FIFO(int iTempPage[N],int flag[N],block myBlock[M])
{
    int i,j,k,loc;
    bool ExistFlag=false;

    //初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
    //同时将目前物理块中的内容输出
    InitialBlock(iTempPage,flag,myBlock);

    //从引用串中的第4个页面开始
    for(i=3;i<N;i++)
    {
        ExistFlag=false;
        for(j=0;j<M;j++)
        {
            //物理块中存在
            if (myBlock[j].iPageNum==iTempPage[i])
            {
                //模拟移位寄存器
                for(k=0;k<M;k++)
                    myBlock[k].iBlockFlag++;

                ExistFlag=true;
                flag[i]=0;
                break;
            }
        }
        //物理块中不存在
        if (!ExistFlag)
        {
            //查找最先进来的页面,也就是block中iBlockFlag最大的物理块
            loc=max(myBlock);
            myBlock[loc].iPageNum=iTempPage[i];

            //置缺页标志
            flag[i]=1;

            //模拟移位寄存器
            for(k=0;k<M;k++)
                if (k!=loc)
                    myBlock[k].iBlockFlag++;
                else
                    myBlock[k].iBlockFlag=0;
        }

        //输出
        output(iTempPage[i],flag[i],myBlock,M);
    }
    cout<<endl;
}

//Optimal置换算法
void Optimal(int iTempPage[N],int flag[N],block myBlock[M])
{
    int i,j,k,loc,maxIndex;
    bool ExistFlag=false;

    //初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
    //同时将目前物理块中的内容输出
    InitialBlock(iTempPage,flag,myBlock);

    //从引用串中的第4个页面开始
    for(i=3;i<N;i++)
    {
        ExistFlag=false;
        for(j=0;j<M;j++)
        {
            //物理块中存在
            if (myBlock[j].iPageNum==iTempPage[i])
            {
                ExistFlag=true;     // 物理块存在,不发生置换
                flag[i]=0;          // 没有缺页,不发生置换
                break;
            }
        }
        //物理块中不存在
        if (!ExistFlag)
        {
            // 查找以后永不使用或者在最长(未来)时间内不再被访问的页面
            maxIndex = i;   // maxIndex初始化为i (后面allocate函数返回的结果都大于i)
            for(k=0;k<3;++k)
            {
                // 计算当前物理块中的三个页面在引用串的还未访问串中页面的位置,并选出这三者的最大值作为loc
                if(maxIndex < allocate(myBlock[k].iPageNum,i+1,iTempPage))    // 如果myBlock[k].iPageNum在未来出现的下标大于maxIndex,则更新maxIndex和loc
                {
                    maxIndex = allocate(myBlock[k].iPageNum,i+1,iTempPage);
                    loc = k;
                }
            }
            // 将loc换出
            myBlock[loc].iPageNum = iTempPage[i];

            //置缺页标志
            flag[i]=1;
        }

        //输出
        output(iTempPage[i],flag[i],myBlock,M);
    }
    cout<<endl;

}

//LRU置换算法
void LRU(int iTempPage[N],int flag[N],block myBlock[M])
{
    int i,j,k,loc;
    bool ExistFlag=false;

    //初始化物理块的内容,因任一种算法在物理块内容为空时,结果都一样的
    //同时将目前物理块中的内容输出
    InitialBlock(iTempPage,flag,myBlock);

    //从引用串中的第4个页面开始
    for(i=3;i<N;i++)
    {
        ExistFlag=false;
        for(j=0;j<M;j++)
        {
            //物理块中存在
            if (myBlock[j].iPageNum==iTempPage[i])
            {
                //模拟移位寄存器
                for(k=0;k<M;k++)
                    myBlock[k].iBlockFlag++;
                // 将第j个物理块上的页面标记为0,表示最近访问过的
                myBlock[j].iBlockFlag = 0;
                ExistFlag=true;
                flag[i]=0;
                break;
            }
        }
        //物理块中不存在
        if (!ExistFlag)
        {
            //查找最先进来的页面,也就是block中iBlockFlag最大的物理块
            loc=max(myBlock);
            myBlock[loc].iPageNum=iTempPage[i];

            //置缺页标志
            flag[i]=1;

            //模拟移位寄存器
            for(k=0;k<M;k++)
                if (k!=loc)
                    myBlock[k].iBlockFlag++;
                else
                    myBlock[k].iBlockFlag=0;
        }

        //输出
        output(iTempPage[i],flag[i],myBlock,M);
    }
    cout<<endl;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
分别有三个程序都能使用!1) 进一步理解父子进程之间的关系。 2) 理解内存页面调度的机理。 3) 掌握页面置换算法的实现方法。 4) 通过实验比较不同调度算法的优劣。 5) 培养综合运用所学知识的能力。 页面置换算法是虚拟存储管理实现的关键,通过本次试验理解内存页面调度的机制,在模拟实现FIFO、LRU等经典页面置换算法的基础上,比较各种置换算法的效率及优缺点,从而了解虚拟存储实现的过程。将不同的置换算法放在不同的子进程中加以模拟,培养综合运用所学知识的能力。 2. 内容及要求: 这是一个综合型实验,要求在掌握父子进程并发执行机制和内存页面置换算法的基础上,能综合运用这两方面的知识,自行编制程序。 程序涉及一个父进程和两个子进程。父进程使用rand()函数随机产生若干随机数,经过处理后,存于一数组Acess_Series[]中,作为内存页面访问的序列。两个子进程根据这个访问序列,分别采用FIFO和LRU两种不同的页面置换算法对内存页面进行调度。要求: 1) 每个子进程应能反映出页面置换的过程,并统计页面置换算法的命中或缺页情况。 设缺页的次数为diseffect。总的页面访问次数为total_instruction。 缺页率 = disaffect/total_instruction 命中率 = 1- disaffect/total_instruction 2)将为进程分配的内存页面数mframe 作为程序的参数,通过多次运行程序,说明FIFO算法存在的Belady现象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值