OS-实验报告5-虚拟存储器管理

实  验  报  告

学生姓名

**,**

学号

******

指导老师

***

实验地点

实验时间

班级

*****

  • 实验室名称:

  • 实验项目名称:

虚拟存储器管理

  • 实验学时:

4学时

  • 实验原理:

虚拟存储器作为现代操作系统中存储器管理的一项重要技术,实现了内存扩充功能。但该功能并非是从物理上实际地扩大内存的容量,而是从逻辑上实现对内存容量的扩充,让用户所感觉到的内存容量比实际内存容量大得多。于是便可以让比内存空间更大的程序运行,或者让更多的用户程序并发运行。这样既满足了用户的需要,又改善了系统的性能。

  • 实验目的:
  1. 学习和编程实现最佳(OPT)页面置换算法
  2. 学习和编程实现先进先出(FIFO)页面置换算法。
  3. 学习和编程实现最近最久未使用(LRU)页面置换算法。
  • 实验内容: 

假定某进程共有8页,且系统为之分配了三个物理块,并有以下页面调度序列∶7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1

使用以下置换算法:最佳置换算法(OPT)、先进先出置换算法(FIFO)、最近最少用置换算法(LRU)。

计算并输出:页面置换情况和缺页率。

最佳置换算法输出效果如下:

OPT:f=0.45

7x,0x,1x,2x,0,3x,0,4x,2,3 ,0x,3,2,1x,2,0,1,7x,0,1

  1. 最佳(OPT)页面置换算法:       
  1. 流程图
  2. 算法分析和描述:
  3. 代码:
  4. 输出截图:
  1. 先进先出(FIFO)页面置换算法:   
  1. 流程图
  2. 算法分析和描述:
  3. 代码:
  4. 输出截图:
  1. 最近最久未使用(LRU)页面置换算法:
  1. 流程图                  
  2. 算法分析和描述:        
  3. 代码:                  
  4. 输出截图:

/**-------------------------------------------------实验开始--------------------------------------------------*/

1、最佳(OPT)页面置换算法:       

(1)流程图:OS-实验报告5-虚拟存储器管理_第1张图片

  1. 算法分析和描述:

OS-实验报告5-虚拟存储器管理_第2张图片

OS-实验报告5-虚拟存储器管理_第3张图片

 OS-实验报告5-虚拟存储器管理_第4张图片

(3)代码:

#include

int num[20] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 };

int A[3] = { -1, -1, -1 };

int physicalBlock[3] = { -1, -1, -1 }; // 3个物理块

bool OPT(int index) {

int i; //标识物理块号

for (i = 0; i < 3; i++) {

if (A[i] == -1) //判断该物理块是否为空物理块

break; //如果当前物理块为空物理块,则证明后面的物理块都为空物理块,需要装入页面。

if (physicalBlock[i] == num[index]) // 判断页面是否在内存中

return true;

}

if (i == 3) { //没有空物理块,需要替换页面

int flag = 0; // 标记有几个物理块的页面在随后的访问中被访问;

for (int m = index + 1; m < 20; m++) {

if (flag == 2) {

break;

}

for (int n = 0; n < 3; n++) { // 遍历物理块

if (num[m] == physicalBlock[n]) { // 该物理块的页面会在随后的访问中被访问

if (A[n] != 0) {

A[n] = 0;

flag++;

}

break;

}

}

}

for (int i = 0; i < 3; i++) {

if (A[i] != 0) {

physicalBlock[i] = num[index]; // 替换出该物理块中的页面

A[i] = 1; // 将标记改成有页面

}

A[i] = 1;

}

return false;

} else {

physicalBlock[i] = num[index]; //第i个物理块中放入页面

A[i] = 1;

return false;

}

}

void OPT1() {

int N = 0; //页面置换次数

for (int i = 0; i < 20; i++) {

bool b = OPT(i);

if (b == true) {

printf("%d   ", num[i]);

}

if (b == false) { //页面发生了置换

printf("%dx   ", num[i]);

N++;

}

}

double d = (double)N / 20 ;

printf("\nOPT:f=%.2f", d);

}

int main() {

OPT1();

}

(4)输出截图:

2.先进先出(FIFO)页面置换算法:

(1)流程图

(2)算法分析和描述:OS-实验报告5-虚拟存储器管理_第5张图片

 OS-实验报告5-虚拟存储器管理_第6张图片

(3)代码:

①主函数

#include

#include

#include "Queue.h"

using namespace std;

void FIFO(int order[20],int visitied[20])

{

    cout<<"先进先出置换算法输出效果如下:"<

    SqQueue Q;InitQueue(Q);      //创建并初始化队列

    int i,j;

    float flag=0,per;   //缺页次数与缺页率

    for(i=0;i<20;i++)          //所要调度序列长度

    {

        if(Queue_FInd(Q,order[i]))   //判断是否缺页

        {//不缺

            visitied[i]=1;

            continue;

        }

        else

        {//缺页

            flag+=1;//缺页次数+1

            if(QueueFull(Q))          //判断物理块是否有剩余

            {//物理块用光了

                DeQueue(Q,j);         //FIFO   //队头出队

                EnQueue(Q,order[i]);           //队尾进队

            }

            else                     //使用剩余物理块

            {//物理块还有剩的

                EnQueue(Q,order[i]);  //入队

            }

            visitied[i]=0;

        }

    }

    per=flag/20;

    printf("FIFO:f=%.2f\n",per);

}

int main()

{

    int Order[20]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};

    int visitied[20];  //为保持输出与规定的一样,现创建一个数组;缺页置0,不缺置1;

    FIFO(Order,visitied);

    for(int i=0;i<20;i++)

    {

        if(visitied[i]==0)

        {

            cout<

        }

        else

        {

            cout<

        }

    }

    return 0;

}

②头文件——Queue.h

#include

#include

using namespace std;

#define MAXSIZE 4    //定义物理块数。实际使用中会少用一个空间来实现循环   队列

#define OK 1

#define ERROR 0

#define OVERFLOW -1

typedef int Status;

typedef struct

{

    int *base;  ///顺序表要加*号,要给空间,存基地址

                //or  int data[MAXSIZE];

    int Front;

    int Rear;

}SqQueue;

///初始化

Status InitQueue(SqQueue &Q)

{

    Q.base=new int[MAXSIZE];

    if(!Q.base) exit(OVERFLOW);

    Q.Front=Q.Rear=0;

    return OK;

}

///入队

Status EnQueue(SqQueue &Q,int e)

{

    if((Q.Rear+1)%MAXSIZE==Q.Front) return OVERFLOW;

    Q.base[Q.Rear]=e;

    Q.Rear=(Q.Rear+1)%MAXSIZE;    ///防溢出

    return OK;

}

///出队

Status DeQueue(SqQueue &Q,int &E)

{

    if(Q.Front==Q.Rear) return ERROR;

    E=Q.base[Q.Front];

    Q.Front=(Q.Front+1)%MAXSIZE;

    return OK;

}

///求队列长度

Status QueueLength(SqQueue Q)

{

    return (Q.Rear-Q.Front+MAXSIZE)%MAXSIZE;

}

///get head Elem

Status GetHead(SqQueue Q)

{

    if(Q.Front!=Q.Rear)

    {

        return Q.base[Q.Front];      //队头指针不变

    }

}

///判空

Status QueueEmpty(SqQueue Q)

{

    if(Q.Front==Q.Rear) return OK;

    else return ERROR;

}

///判满

bool QueueFull(SqQueue Q)

{

    if((Q.Rear+1)%MAXSIZE==Q.Front) return true;

    else return false;

}

///遍历队列查找

bool Queue_FInd(SqQueue Q,int E)

{

    int i,head,rear;

    head=Q.Front;rear=Q.Rear;

    /*if(QueueEmpty(Q))

    {

        cout<<"队列为空";

        return false;

    }*/

    for(i=0;i

    {

        if(Q.base[head]==E)

        {

            return true;

        }

        head=(head+1)%MAXSIZE;

    }

    if(i==QueueLength(Q))

    {

        return false;

    }

}

///打印队列

int Queue_Printf(SqQueue Q)

{

    int i,head;

    head=Q.Front;

    if(QueueEmpty(Q))

    {

        cout<<"队列为空";

        return ERROR;

    }

    for(i=0;i

    {

        cout<

        head=(head+1)%MAXSIZE;

    }

}

(4)输出截图:

OS-实验报告5-虚拟存储器管理_第7张图片

3.最近最久未使用(LRU)页面置换算法:

(1)流程图             

(2)算法分析和描述:     

OS-实验报告5-虚拟存储器管理_第8张图片

OS-实验报告5-虚拟存储器管理_第9张图片

(3)代码:(头文件——Queue.h 同上 此处略)

#include

#include

#include "Queue.h"

using namespace std;

///交换数值

void Swap(int &a,int &b)

{

    int t;

    t=a;

    a=b;

    b=t;

}

/**-----改变队列内元素顺序----*/

void Change_QElem(SqQueue &Q,int E)

{

    int L,Locate2;

    L=(Q.Front+QueueLength(Q)-1)%MAXSIZE;  //确定队尾元素的位置

    Locate2=(Q.Front+1)%MAXSIZE;   //确定队头后一个元素的位置

    if(Q.base[L]==E);//队尾元素是最新页,无需变换队列元素顺序

    else

    {//队尾元素不是最新页

        if(L==Locate2)      //队列只有两个元素时

        {

            Swap(Q.base[L],Q.base[Q.Front]);    //两个元素进行交换

        }

        else         //队列有三个元素时即队满,有两种情况:①队头是最新页②队头后一个元素是最新页

        {

            if(Q.base[Q.Front]==E)   //①

            {

                //方法一:利用第四个空间

                Q.base[Q.Rear]=Q.base[Q.Front];

                Q.base[Q.Front]=NULL;

                Q.Front=(Q.Front+1)%MAXSIZE;

                Q.Rear=(Q.Rear+1)%MAXSIZE;

                //方法二:两次交换

                /*Swap(Q.base[Q.Front],Q.base[Locate2]);

                Swap(Q.base[Locate2],Q.base[L]);*/

            }

            else                  //②

            {

                Swap(Q.base[L],Q.base[Locate2]);  //两个元素进行交换

            }

        }

    }

}

/**-------LRU--------*/

void LRU(int Order[20],int visited[20])

{

    int i=0,E;

    float flag=0,per;          //定义缺页次数与缺页率

    SqQueue Q;InitQueue(Q);

    for(i=0;i<20;i++)

    {

        if(Queue_FInd(Q,Order[i]))     //判断是否缺页

        {//不缺页

            visited[i]=1;

            Change_QElem(Q,Order[i]); ///按最近最久来重新排序队列内元素

        }

        else

        {//缺页

            flag+=1; //缺页次数+1

            if(QueueFull(Q))           //判断物理块是否有剩余

            {//无剩余

                DeQueue(Q,E);          //队头(最近最久未使用的页)出队

                EnQueue(Q,Order[i]);

            }

            else

            {//有剩余

                EnQueue(Q,Order[i]);

            }

            visited[i]=0;

        }

    }

    per=flag/20;

    cout<<"最佳置换算法输出效果如下"<

    printf("LRU:f=%.2f\n",per);

}

int main()

{

    int Order[20]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1};

    int visitied[20];  //为保持输出与规定的一样,现创建一个数组;缺页置0,不缺置1;

    LRU(Order,visitied);

    for(int i=0;i<20;i++)

    {

        if(visitied[i]==0)

        {

            cout<

        }

        else

        {

            cout<

        }

    }

    return 0;

}

(4)输出截图:

你可能感兴趣的:(os)