【操作系统实践--内存管理】

一、实验目的

  1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解。
  2. 促进对虚拟存储管理的页面淘汰算法的理解。

二、实验内容

设计一个请求页式存储管理方案:编写模拟程序实现,产生一个需要访问的指令地址流,它是一系列需要访问的指令的虚拟地址。页面淘汰算法采用时钟页面置换算法,并且在淘汰一页时,只将该页在页表中抹去,不再判断它是否被改写过,也不将它写回到辅存。

  1. 指定合适的页面尺寸。
  2. 指定内存页表的最大长度,并对页表进行初始化。
  3. 输入一个需要访问的指令虚拟地址。
  4. 每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存如果该页已在主存,则打印页表情况。
  5. 如果该页不在主存且页表未满,则调入一页并打印页表情况。
  6. 如果该页不在主存且主存已满,则按时钟页面淘汰算法淘汰一页后调入所需的页,打印页表情况。
  7. 逐个地址访问,直到所有地址访问完毕。

三、编程环境及工具

Dev-C++ 5.11

四、具体设计及有关说明

设计思想:

  1. 创建循环链表,进行初始化;
  2. 创建页表结构体数组,进行初始化;
  3. 开始进行循环:输入虚拟地址,运算出虚拟地址对应的页数,①输入虚拟地址不存在或者超出页数的情况,结束循环;②通过页数与循环链表的一一对比判断该页在主存中:更新循环链表对应物理页帧的最近访问状态,更新页表结构体数组的信息;③页不在主存中:若主存已满,通过循环链表里指针的移动替换出对比其他最先进入的虚拟地址页(若此时虚拟地址页对应的主存刚被访问,则指针向下遍历,直到找到不是最近访问到的物理页帧),更新链表与数组的信息;若主存未满,直接进行信息的更新即可;④一次循环的最后,进行页表信息的输出;

数据结构:

运用了循环链表来表示物理页帧,让指针可以在链表里循环移动,以此来表示最先进入的虚拟地址页;

流程图:

在这里插入图片描述

五、代码:

#include<bits/stdc++.h>
#include<conio.h>   
using namespace std;

#define P_area 4096  //定义固定数值 
#define P_page 4
#define V_page 8

//定义页表的结构体,结构体包含虚拟页对应的物理页帧号、页帧号对应页的近期访问状况、存在状况
typedef struct V_Address 
{
	int Pa_num;
	int R;
	int p;
}vad;

//定义物理页帧号的结构体,结构体包含对应的虚拟页号、页帧号对应页的近期访问状况、页帧号、 物理地址结构体指针    
typedef struct node
{
	int page;
	int R; 
	int Pa_num;
	struct node *next;
}Node;
  
int main()
{
	int i,m_empty;
	m_empty = P_page;  //empty用于表示剩余的物理地址页帧数 

	//创建循环链表,表长为物理页帧数 P_page 
	Node *pre = new Node;  //定义结构体指针pre为指向循环链表表头的指针 
	Node *r = new Node;
	pre->page = -1;  //对应的虚拟页号暂时未知,所以赋值为-1 
	pre->R = 0;  //初始状态为未访问状态 
	pre->Pa_num = 0;  //表头的物理页帧数从零开始 
	pre->next = NULL;  
	r = pre;
	for(i = 1;i < P_page;i++)
	{ 
		Node *p = new Node;
		p->page = -1;
		p->R = 0;
		p->Pa_num = i;  //物理页帧数为3时,循环结束 
		r->next = p;
		r = p;
	}
	r->next = pre;  //令表尾指针指向表头,构成循环链表 
	
	//将虚拟地址初始化 
	vad* pa = new vad[V_page];
	for(i = 0;i < V_page;i++)
	{
		pa[i].p = 0;
		pa[i].Pa_num = 0;
		pa[i].R = 0;
	}
	
	printf("此示例程序定义页面大小为%dB,",P_area);
	printf("定义分配给进程的物理页帧数为%d页,定义进程的虚拟地址空间大小为%d页。(^_^)\n",P_page,V_page);
	
	//循环过程,不断循环 
	while(true)
	{
		int address,a_page,in_RAM;
		in_RAM = 0;  //作为标记,0时表示不在主存,1表示在主存 
		printf("(^_^)please input the virtual address<end of -1>:");
		scanf("%d",&address);  //输入虚拟地址 
		a_page = address / P_area;  //算出虚拟地址所在的页数,页数从零开始
		
		//讨论输入虚拟地址不存在或者超出页数的情况,结束循环 
		if(a_page > V_page || address < 0)
		{
			printf("fatal error,illegal address!!\n");
			printf("the process will exit with error!!\n");
			getch();
			break;
		}
		
		//将循环链表循环一遍,判断页是否在主存当中 
		r = pre;
		for(i = 0;i < P_page;i++)
		{
			//页在主存的情况 
			if(r->page == a_page)
			{
				in_RAM = 1;	 //判断值赋值为1 
				if(r == pre) 
					r->R = 1;  //物理页帧结构体的R为1,代表此时指针所指的结构体为最近访问 
				pa[a_page].Pa_num = r->Pa_num;  //用于表示虚拟页数对应的物理页帧数 
				pa[a_page].R = 1;  //用于表示该物理页帧最近访问过 
				printf("the page is in the RAM!,and the physical address is %d\n",address);
				break;
			}
			r = r->next;
		}  //循环结束后,可以得到是否在主存中的判断值 
		
		//页不在主存的情况		
		if(in_RAM==0)
		{
			printf("the page is not in the RAM!\n");
			//主存已满 
			if(m_empty == 0)
			{
				printf("there are no free pages,so we have to exchange one!\n");
				//指针所指处为对比其他页帧最先进入的,遵循先进先出原则,从物理页帧队列的指针所指处开始循环,判断指针所指是否为最近访问 
				for(;pre->R == 1;pre = pre->next)
				{ 
					pre->R = 0;  //如果为最近访问,则令最近访问的判断数为零,指针向下循环 
					printf("page NO.%d is just read,we should search next one!\n",pre->Pa_num);
				} //跳出此循环后,指针所指页帧为所要替换的 
				pa[pre->page].p = 0;  //此时被替换,虚拟页号对应的物理页帧号无效 
				printf("NO.%d page is exchanged!!\n",pre->Pa_num);
			}
			//主存未满 
			else
			{
				m_empty--;
				printf("there are free pages,we can get NO.%d page!\n",pre->Pa_num);
			}
			//对信息进行更新 
			pre->page = a_page;
			pa[a_page].p = 1;
			pa[a_page].R = 1;
			pa[a_page].Pa_num = pre->Pa_num;
			pre = pre->next;  //指针向下循环 
		}
		
		//输出页表情况 
		printf(" pa_num\tR\tP\n");
		for(i = 0;i < V_page;i++)
		{
			printf("  |%d\t|%d\t|%d\n",pa[i].Pa_num,pa[i].R,pa[i].p);
		}
		pa[a_page].R = 0;  //在一次循环的最后将页表数组的全部最近访问情况判断数置为零
		                   //这样只需在访问到时将访问到的置为1,不需要考虑是否存在其他物理页帧的状态也为1 
	}
	return 0;
 }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值