[问题描述] 设计一个请求页式存储管理方案,为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中修改状态位。而不再判断它是否被改写过,也不将它写回到辅存。
[基本要求]
页面尺寸1K,输入进程大小(例如5300bytes),对页表进行初始化,
页表结构:
页 号 | 物理块号 | 状态位 |
0 | 2 | True (在主存) |
1 | 1 |
|
2 |
| False (在辅存) |
3 | 0 |
|
4 |
| False (在辅存) |
5 |
| False (在辅存) |
系统为进程分配3 个物理块(页框),块号分别为0、1、2,页框管理表(空闲块表):
物理块号 | 是否空闲 |
0 | true |
1 | true |
2 | true |
任意输入一个需要访问的指令地址流(例如:3635、3642、1140、0087、1700、5200、4355,输入负数结束),打印页表情况。
每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满 ,则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况;#include<stdio.h>
#include<stdlib.h>
int P_Size ; //进程大小
int Ask_Address; //询问地址
int num; //当前页号
int Count = 0 ;
struct Table_Page{
// int P_num; //页号
int B_num; //物理块号
int State; //状态
};
struct Table_Block{
int Count; //物理块号
int Judge; //是否空闲
};
Table_Page TP[6];
Table_Block TB[4];
void Init(){
printf("请输入进程的大小:");
scanf("%d",&P_Size);
}
//打印页表
void Print_TP(){
int i, j;
for (i = 0; i < 6; i++){
printf("页号:%d 物理块号:%d 状态:%d count:%d\n", i,TP[i].B_num,TP[i].State ,TB[TP[i].B_num].Count);
}
}
//计算页号
//传入参数:地址
//传出参数:页号
int Count_PageNumber(int address){
return address / 1024 + 1;
}
//判断逻辑页号是否在内存中
//传入参数:页号
//传出参数:1 在 0 不在
int Judge(int num){
if (TP[num].State == 0)
printf("该页号不再内存中\n");
else
printf("该页号在内存中\n");
return TP[num].State;
}
//页框是否还有空闲
//返回值:1未满
//0 已满
int Judge02(){
int i, j;
for (i = 1; i < 4; i++)
if (TB[i].Judge == 0){
printf("页框还有空闲\n");
return 1;
}
printf("页框已满\n");
return 0;
}
//页框未满修改页表
//传入参数:页号
void Edit_TP(){
int i, j;
for (i = 1; i < 4; i++){
if (TB[i].Judge == 0){
TB[i].Judge = 1;
TB[i].Count = ++Count;
TP[num].State = 1;
TP[num].B_num = i;
i = 4;
}
}
}
//页框已满淘汰
//返回参数:淘汰的页
int Throw(){
int i , j;
int min = 100;
int q ;
for (i = 1; i < 4; i++){
if (TB[i].Count < min){
min = TB[i].Count;
q = i;
}
}
for (j = 0; j < 6; j++)
if (TP[j].B_num == q)
return j;
}
//页框已满修改页表
//输入参数:物理块号 , 页表号
void Edit_TP2(int P_num , int B_num ){
TP[P_num].State = 0;
TP[P_num].B_num = 0;
TB[B_num].Count = ++Count;
TB[B_num].Judge = 1;
TP[num].B_num = B_num;
TP[num].State = 1;
}
int main(){
Init();
Print_TP();
while (1){
printf("请输入要访问的地址:");
scanf("%d", &Ask_Address);
if (Ask_Address < 0){
break;
}
if (Ask_Address > P_Size){
printf("地址越界\n");
}
num = Count_PageNumber(Ask_Address);
printf("当前页号:%d\n",num);
if (Judge(num)){
Print_TP();
TB[TP[num].B_num].Count=++Count;
}
else{
if (Judge02()){
Edit_TP();
Print_TP();
}
else{
Edit_TP2(Throw(),TP[Throw()].B_num);
Print_TP();
}
}
}
int test;
scanf("%d",&test);
return 0;
}