页面调度-FIFO

来源:互联网 发布:最快的开方算法 编辑:程序博客网 时间:2024/06/08 16:46

1. 原理
这里写图片描述
图1:请求页式存储管理模拟程序的完整流程图

这里写图片描述
图2:一条指令执行的模拟流程图

这里写图片描述
图3:模拟地址转换的流程图

这里写图片描述
图4:采用FIFO页面置换算法的缺页中断流程图

2.C++ code

// Page_V1.cpp : 定义控制台应用程序的入口点。/**Name:Page_V1.cpp*Author:WangLin*Created On:2015/11/16*Function:模拟页面调度。地址转换:十进制输入,十进制输出*/#include "stdafx.h"#include<iostream>using namespace std;const int  N=64;//页表最大长度int n;//页表实际长度int m;//队列长度int head=0,tail=0,used[N],p[N];//队列头/尾指针/标记数组,存放页号的优先队列struct//页表{    int Number;//页号    int pNumber;//物理块号    int dNumber;//在磁盘上的位置    int write;//修改标志    int flag;//存在标志}page[N];void printPageTable()//打印页表内容{    cout<<"当前页表内容为:"        <<endl<<"================================================================================"<<endl;    cout<<"页号       "<<"物理块号    "<<"磁盘位置    "<<"修改标志    "<<"存在标志    "<<endl        <<"================================================================================"<<endl;    for(int i=0;i<n;++i)    {        cout<<page[i].Number<<"     ";        cout<<page[i].pNumber<<"        ";        cout<<page[i].dNumber<<"        ";        cout<<page[i].write<<"      ";        cout<<page[i].flag<<"       "<<endl;    }}void printQueue()//打印优先队列内容{    cout<<"======================="<<endl<<"当前队列为:"<<endl;    cout<<"-队首-"<<endl;    int i=head,j=0;    while(1)    {        if(used[i]==-1)            cout<<"页号"<<p[i]<<endl;         j++;        if(j==m)break;        i=(i+1)%m;    }    cout<<"-队尾-"<<endl;}void creatPageTable()//创建页表{    int i=0;    cout<<"输入页表的信息,创建页表"<<endl<<"请输入页表项数n:";    cin>>n;    while(i<n)    {        cout<<"输入第"<<i<<"页的辅存地址:";        cin>>page[i].dNumber;        page[i].Number=i;        page[i].pNumber=-1;        page[i].write=page[i].flag=0;        i++;    }    cout<<"页表创建完毕!"<<endl;    printPageTable();    //为进程分配主存    cout<<"输入分配给该进程的主存块数(<"<<n<<"):";    cin>>m;    int *p=new int[m];    cout<<"当前页号队列为空!"<<endl;    //return p;}void startOperate()//指令执行{    cout<<endl<<"++++++++++++++++++++++++++++++++++++"<<endl<<"开始指令操作!"<<endl<<endl;    int i,lgcaddr,ad,paddr;//页号,逻辑地址,页内偏移,物理地址    char ch;    //cout<<"输入要调用的页号(<"<<n<<"):";    cout<<"输入逻辑地址:";    cin>>lgcaddr;    cout<<endl<<"是否对页进行修改(y/n):";    cin>>ch;    i=lgcaddr>>10;//页号    ad=lgcaddr&0x3ff;//页内偏移    if(i<n)    {        //第1步,查看页表        if(page[i].flag==1)//在内存中,即在页号队列p[]中,形成物理地址输出        {            cout<<"第"<<i<<"页已在主存中,物理地址是:";            i=page[i].pNumber;//由页号找到物理块号            paddr=i<<10|ad;//合并物理块号和页内偏移,形成物理地址            cout<<paddr<<endl;        }        else//不在内存中,从磁盘中调入到p[]中,插在队尾        {            cout<<"从磁盘"<<page[i].dNumber<<"调入页"<<i<<"..."<<endl;            if(used[tail]!=-1)//如果队列未满            {                p[tail]=i;//插在队列尾部                used[tail]=-1;//标记队列此处已被占用                page[i].pNumber=tail;//物理块为此时队列位置下标                page[i].flag=1;//修改标志为存在                tail=(tail+1)%m;//tail指向下一个位置                //如果要修改页表                if(ch=='y'||ch=='Y')page[i].write=1;                cout<<"页号"<<i<<"    成功调入内存!"<<endl;            }            else//队列已满,选择队首替换出去            {                //淘汰队首页                cout<<"队列已满!淘汰队首页,页号为"<<p[head]<<endl;                page[p[head]].flag=page[p[head]].pNumber=0;                if(page[p[head]].write==1){cout<<"页号"<<p[head]<<"   内容写入到辅存!";}//换出之前写入到辅存中                page[p[head]].write=0;                cout<<endl<<"页号"<<p[head]<<"    淘汰成功!"<<endl;                page[i].flag=1;                page[i].pNumber=head;                page[i].write=0;                p[head]=i;                head=(head+1)%m;                cout<<"页号"<<i<<"    成功调入内存!"<<endl;            }            //形成物理地址输出            cout<<"第"<<i<<"页的物理地址是:";            i=page[i].pNumber;//由页号找到物理块号            paddr=i<<10|ad;//合并物理块号和页内偏移,形成物理地址            cout<<paddr<<endl;        }        cout<<endl<<"是否打印页表和队列(y/n):";        cin>>ch;        if(ch=='y'||ch=='Y')        {            printPageTable();            printQueue();        }    }    else        cout<<"输入的页号大于页表长度,越界!页面调度失败:"<<endl;    cout<<"指令执行完毕!"<<endl<<"++++++++++++++++++++++++++++++++++++"<<endl;}int _tmain(int argc, _TCHAR* argv[]){    creatPageTable();//p是页号队列    char ch='y';    while(ch=='y'||ch=='Y')    {        startOperate();        cout<<"继续执行指令(y/n):";        cin>>ch;    }    return 0;}

3. 运行结果
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述


4 .总结
本实验中,对队列的处理有些粗糙,仅仅能保证正确,质量不高,用used[]标记数组个人感觉也是很笨拙的办法。另外,代码多处都可以进一步优化,总之还有许多不足的地方,有空再继续回来修改。


小技巧:直接在dos下用python的bin(a)函数和int(”,2)函数可以检测十进制和而二进制的转换。
python相当于简易计算器啊~~

这里写图片描述

0 0
原创粉丝点击