Part7. 存储管理
往期回顾:
Part0. 实验环境
Part1-1.熟悉UKylin环境
Part1-2.熟悉UKylin环境
Part2.进程控制
Part3.进程通信
Part4.管道通信
Part5.避免死锁——银行家算法的实现
Part6. 进程调度算法的模拟实现
一、实验目的
通过编程模拟实现请求页式存储管理的几种常用页面置换算法,了解虚拟页式存储管理的特点,掌握请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并进行比较。
二、实验内容
1.(必做)设计一个虚拟存储区和内存工作区,采用固定分配局部置换策略,并使用下述算法计算采用不同页面置换算法的访问命中率。
三、实验准备
本实验的程序设计基本上按照实验内容进行,用C语言编写程序。首先用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: A:50%的指令是顺序执行的
B:25%的指令是均匀分布在前地址部分 C:25%的指令是均匀分布在后地址部分 (2)将指令序列变换为页地址流
(3)对所产生的地址流,分别采用不同的页面置换算法计算出相应的命中率。分别计算驻留集大小为4~8,不同算法的命中率。
(4)用户逻辑空间保持不变,还是32KB。取页面大小分别为2KB、4KB、8KB时,重复步骤(2)~(3)分别计算驻留集大小为4个页框到8个页框时,对于相同的随机指令序列,不同算法的命中率。
四、实验程序流程图
五、实验代码
/************************************************************************
程序功能:通过编程模拟实现请求页式存储管理的几种常用页面置换算法,
了解虚拟页式存储管理的特点,掌握请求页式存储管理中几种基本
页面置换算法的基本思想和实现过程,并进行比较。
完成日期:2020/05/24
版本:v1.0
*************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h> //malloc()函数、rand()函数包含在头文件stdlib.h中,要使用它必须用#include<stdlib.h>引入该头文件;
#include<time.h> //要使用time()函数,先要通过#include<time.h>引入time.h头文件
#define N 320
int rand_array[400]; //模拟虚拟存储区,存储随机生成的320个指令序列
int page_stream[400]; //将指令序列变换成相应的页地址流
int page_times[400]; //LFU算法使用,下标表示页号,值表示次数
int *resident_array; //驻留集,模拟内存工作区
int *clock_status; //Clock页面置换算法中的访问位数组
bool exist_page[400]; //标记已存在于某一物理块中的页号,下标表示页号,为true表示存在
int t = 0; //数组全局变量下标
int choice; //选择页面置换算法的序号
int page_count = 0; //计数,累计缺页次数
int page_size = 0; //页面大小,单位为KB,取值为(1,2,4,8)
int resident_set = 4; //驻留集大小,取值为(4~8)
int replace_page = -1; //即将要进行页面替换的旧页面
int rep = 0; //即将替换的旧页面在驻留集中的下标
FILE *fp;
int def_rand(int a,int b); //生成一个[a,b]的随机数
int rand_solve(int a,int b); //将随机数存入rand_array数组
void creat_rand_array(); //产生需要执行的指令序列,若发生越界则跳过
void excute_all_choices(); //根据用户输入的页面大小,输出在驻留集不同的情况下,各置换算法的命中率
void create_page_stream(); //将指令序列变换成相应的页地址流
void algorithm_menu(); //页面置换算法选择菜单
void replace_pages(); //根据随机产生的页面地址流,进行页面访问的过程模拟,由所选的算法进行页面置换
void OPT(int t); //最佳淘汰算法(OPT)
void FIFO(int t,int *fptr); //先进先出算法(FIFO)
void LRU(int t); //最近最久未使用算法(LRU)
void LFU(int t); //最不经常使用算法(LFU)
void Clock(int i,int *cptr); //Clock页面置换算法
/**********************主函数**************************/
int main()
{
creat_rand_array(); //随机生成指令序列
fp = fopen("result.txt","w"); //打开文件,将执行过程写入result.txt文件
if(fp == NULL)
{
printf("File cannot open!\n");
exit(0);
}
while(1)
{
char YorN = 'Y';
printf("**********此系统将模拟实现请求页式存储理的几种常用页面置换算法**********\n");
fprintf(fp,"**********此系统将模拟实现请求页式存储理的几种常用页面置换算法**********\n");
printf("\n请问是否要进入系统?(格式:Y/y or N/n)请输入:");
scanf("%c",&YorN);
getchar();
if(YorN == 'N' || YorN == 'n')
{
printf("执行结束,系统已退出!\n");
break;
}
else if(YorN == 'Y' || YorN == 'y') excute_all_choices(); //核心!
else printf("请您按要求输入合法字符!\n\n"); //防止出现非法字符的输入
}
fclose(fp); //关闭文件
return 0;
}
/************************************
函数名称:algorithm_menu()
函数功能:页面置换算法选择菜单
返回值:无
*************************************/
void algorithm_menu()
{
char str_OPT[] = "1.最佳淘汰算法(OPT)";
char str_FIFO[] = "2.先进先出算法(FIFO)";
char str_LRU[] = "3.最近最久未使用算法(LRU)";
char str_LFU[] = "4.最不经常使用算法(LFU)";
char str_Clock[] = "5.Clock页面置换算法";
for(int i = 0; i < 60; i++) printf("*");
printf("\n*\t\t%s",str_OPT);
for(int i = 0; i < 43 - strlen(str_OPT); i++) printf(" ");
printf("*\n*\t\t%s",str_FIFO);
for(int i = 0; i < 43 - strlen(str_FIFO); i++) printf(" ");
printf("*\n*\t\t%s",str_LRU);
for(int i = 0; i < 43 - strlen(str_LRU); i++) printf(" ");
printf("*\n*\t\t%s",str_LFU);
for(int i = 0; i < 43 - st