操作系统课程设计
实验报告
学院:信息学院
班级:计1109班
姓名:林海慧
学号:XXXXXXXXXXXXX
指导老师:XXXX
实验三、内存管理
一、[问题描述] 设计一个请求页式存储管理方案,为简单起见。
页面淘汰算法采用FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中修改状态位。
而不再判断它是否被改写过,也不将它写回到辅存。
二、[基本要求]
页面尺寸1K,输入进程大小(例如5300bytes),对页表进行初始化,
页表结构:
,块号分别为0、1、2,页框管理表(空闲块表):
任意输入一个需要访问的指令地址流(例如:3635、3642、1140、0087、1700、5200、4355,输入负数结束),打印页表情况。
每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满,则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则按FIFO页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况;
存储管理算法的流程图如下:
三、源代码
#include <stdio.h>
#include <stdlib.h>
#define BUSY 1
#define NOTBUSY 0
struct PageB{
int PNumber; //页号
int BNumber; //物理块号
int Count; //计数器,在内存驻留时间
bool State; //状态位
} ;
PageB
Page[6]={{0,-1,0,false},{1,-1,0,false},{2,-1,0,false},{3,-1,0,false},{4,-1,0,false},{5,-1,0,false}};
int queye=0;
struct Physical{
int BNumber; //物理块号
int State; //状态位
}Physical[3]={{0,0},{1,0},{2,0}};
int MaxSzie, MaxCount = 0;
bool IsInPage(int P)//判断是否在内存
{
int i=0;
int flag=0;
for (i = 0; i <= 5; i++)
{
if (Page[i].PNumber == P && Page[i].State == true)
{
printf("\n页在主存,打印页表:");
printf("\n页号:%d 物理块号:%d 状态:%d(true)",Page[i].PNumber,Page[i].BNumber,Page[i].State);
flag=1;
}
}
if(flag==1)
return true;
else return false;
}
void FIFO(int P)//FIFO页面置换算法
{
int i, j, k;
int BNumber;//暂存物理块号
for(i = 0; i <= 5; i++)
{
if (Page[i].PNumber == P && Page[i].State == false)
{
printf("页号%d在辅存\n",P);
//分配给该进程的物理块均被占
if(Physical[0].State == BUSY && Physical[1].State == BUSY && Physical[2].State == BUSY)
{
MaxCount=0;
for (j = 0; j <= 5; j++)
{
if (Page[j].Count >= MaxCount && Page[j].State == true)
{
MaxCount = Page[j].Count;
k = j;
}
}
BNumber = Page[k].BNumber;
Page[k].Count = 0;
Page[k].State = false;
Page[k].BNumber=-1;
Page[i].BNumber = BNumber;
Page[i].State = true;
for (j = 0; j <= 5; j++)
if (Page[j].State == true)//驻留在内存的页号时间增加
Page[j].Count = Page[j].Count + 1;
printf("\n页在辅存并已调入主存,打印页表:");
printf("\n页号:%d 物理块号:%d 状态:%d(true)",Page[i].PNumber,Page[i].BNumber,Page[i].State);
}
else //分配给该进程的物理块有空闲
{
for (j = 0; j <= 2 ; j++)
{
if (Physical[j].State == NOTBUSY)
{
Page[i].BNumber = Physical[j].BNumber;
Page[i].State = true;
Physical[j].State=BUSY;
for (j = 0; j <= 5; j++)//驻留在内存的页号时间增加
if (Page[j].State == true)
Page[j].Count = Page[j].Count + 1;
printf("\n页在辅存,打印页表:");
printf("\n页号:%d 物理块号:%d 状态:%d(true)",Page[i].PNumber,Page[i].BNumber,Page[i].State);
}
}
}
}
}
}
void DisFIFO()//查看内存物理块号使用情况
{
printf("\n物理块号页表号\n");
for(int w=5;w>=0;w--)
{
if(Page[w].State==true)
printf(" %d %d\n",Page[w].BNumber,Page[w].PNumber);
}
}
int main()
{
int P;
printf("\n请求页式存储管理\n:");
printf("*********为该进程分配的所有内存块都是空闲的\n**********:");
printf("\n输入进程大小:");
scanf("%d",&MaxSzie);//输入进程大小
DisFIFO();
int Address;
while(1)
{
printf("\n输入地址:");
scanf("%d",&Address);//输入要访问的地址
while(Address < 0 || Address > MaxSzie)
{
printf("输入地址溢出");
printf("\n请重新输入地址:");
scanf("%d",&Address);
}
P = Address / 1024;//判断页号
if(!IsInPage(P))
{
queye++;
FIFO(P);
}
DisFIFO();
getchar();
char ch;
printf("\n继续输入:y:");
scanf("%c",&ch);
if(ch!='y')
break;
}
printf("此次运行缺页次数为:%d\n",queye);
return 0;
}
四、运行结果
五、遇见的问题
开始时,对请求页式存储管理原理不理解,经过看书、查资料、跟同学讨论,理解后结合课件,终于写出程序。
可见对理论知识掌握的重要性。