1、 实现分页式存储管理地址转换过程,将逻辑地址转换成物理地址。

2、 在此基础上实现请求分页的地址转换;实现请求页式地址转换中出现的缺页现象中,用到的先进先出、最近最久未使用、最佳置换算法。掌握内存的分配方法和虚拟存储器的概念和原理。

利用键盘输入本模拟系统分配给作业的内存物理块个数,作业在执行过程中的页面调度次序。计算出三种算法的缺页次数和缺页率。

 

先说下什么是页(页面):就是将用户的程序的的地址空间分成固定大小的区域,称为”页“,或者”页面“

 

之后将这些页离散的放进内存中,这样解决了内存的碎片问题

 

记得老师上课说了下这两个概念不能混,现在区分下:

 

在第4章存储器管理,学习了分页式存储管理方式(是为了解决内存的碎片问题)

 

在第5章虚拟存储器,学习了请求分页式管理方式(除了解决碎片问题外,又“扩充”了内存的大小(虚拟))

 

在这里为了使得固定数目的内存来运行较多的进程,增加了调页功能和页面置换功能。

页面置换用到了三种方法

1.先进先出(FIFO),最先得到内存的最先置换它    

 2最近最久未使用(LRU),和FIFO差不多,只是把命中的页面放在最不应该淘汰的位置(栈顶,或者栈低,不同的老师有不同的讲法),就是说新来的将最晚被淘汰  

 3最佳置换方法,这个只是用来评估的算法,它要预测将来谁是最迟要内存的(因为它目前不用内存,先让别人用内存),把它先淘汰。

 

下面是流程图,你们不要嫌弃我~我真不会把流程图插进来,只好截图了(可是本姑娘已经对齐了~)

再下面是代码~你们知道怎么插入代码么~为啥我的那么难看

写代码的过程中有几个问题,我在下面用黄色笔标注出来!编译器vs2010

有一些全局变量是想到啥就直接加的,你们看起看可能也会非常费劲。主要注意思想,看别人代码是个超级烦的事情。我很少很少很少看别人写的代码

所以我觉得我写代码就非常罗嗦,一点不简洁。这个是我第一次发这个东西,我以后写的时候尽可能注意简洁性。

你们要是有不懂的就在下面问吧~

 

分页存储 python 分页存储管理方式例题_分页存储 python

分页存储 python 分页存储管理方式例题_缺页_02

#include<iostream>
#include<vector>
#include<string>
using namespace std;typedef struct Pagetable
{
	int physicalblock_No;//物理块号
	int state;//状态位
}PT;
typedef struct Pagetable3
{
	int physicalblock_No3;//物理块号
	int state3;//状态位
}PT3;
int fifo;
int lru;
int opti;
int opt[25];//保存出现过的页号
int h=0;
PT pt[100];
PT3 pt3[100];
int COUNT;
vector<int> stack;//FIFO栈
vector<int> stack2;//LRU栈
vector<int> stack3;//optimal栈
int physical_block;//内存块数
int page_size;//页大小
int pagetable_len;//页表长度
int m[8][8];//位示图
int PageAdd;//页内地址
void Inite();//初始化位示图
void showwst();//显示位视图
void showqyl();//显示缺页率
int call_in();//调入页面
void LRU(int page_no);//
void FIFO(int page_no);//
void optimal(int pageno);
void showstack();//显示栈
void showstack2();//LRU
void showstack3();//opti
int w;
void main()
{
	Inite();
	int logic_add;
	cout<<"输入所分配的内存块数";
	cin>>physical_block;
	int a;
	cout<<"输入页面大小(kb)";
	cin>>page_size;
	cout<<"输入页表长度";
	cin>>pagetable_len;
	int i;
	for(int i=0;i<pagetable_len;i++)//最开始页表的状态位都是0
	{
		pt[i].state=0;
	}
	int PageNo;
	int count=0;
	do{
		COUNT++;
		do
		{
			a=0;
			cout<<"输入逻辑地址";
			count=count+1;
			cin>>hex>>logic_add;//我在这里是以16进制的方式输入的地址,在下面的所有代码却都默认为16进制了!!!!!为何啊?
			PageNo=logic_add/(1024*page_size);//页号			if(PageNo>=pagetable_len)
			{
				a=1;
				cout<<"越界中断请重新输入"<<endl;
			}			}while(a==1);

		cout<<"页号"<<PageNo<<endl;
		opt[h]=PageNo;
		h++;
		PageAdd=logic_add%(1024*page_size);//页内地址
		cout<<"页内地址"<<hex<<PageAdd<<endl;
		/*if(pt[PageNo].state==0)
		{
			cout<<"此页不在内存!正在查找是否有剩余物理块......"<<endl;
		}*/
		if(stack.size()==physical_block)//栈满了
		{
			cout<<"FIFO"<<endl;
			FIFO(PageNo);
			cout<<"LRU"<<endl;
			LRU(PageNo);		}
		else//栈没满
		{
			int n=0;
			for(int i=0;i<stack.size();i++)
			{
				if(stack[i]==PageNo)
				{
					cout<<"命中"<<endl;
					 cout<<"物理地址"<<endl<<hex<<pt[PageNo].physicalblock_No*1024+PageAdd;
					 n=1;
					 break;
				}
			}
			if(n==0)
			{
				cout<<"内存有剩余,可以从位示图中分配内存(物理块号)"<<endl;
				int local=call_in();//
				pt[PageNo].physicalblock_No=local;//页表
				cout<<"物理地址"<<endl;
				cout<<hex<<local*page_size*1024+PageAdd<<endl;
				stack.push_back(PageNo);
				stack2.push_back(PageNo);
				stack3.push_back(PageNo);
				cout<<"FIFO"<<endl;
				showstack();
				cout<<"LRU"<<endl;
				showstack2();
				cout<<"最佳置换"<<endl;
				showstack3();
				pt[PageNo].physicalblock_No=local;
				pt[PageNo].state=1;
				pt3[PageNo].physicalblock_No3=local;
				pt3[PageNo].state3=1;
			}
		}
		cout<<"是否继续输入 1是   2否"<<endl;
		cin>>i;
	}while(i!=2);

	cout<<"最佳置换"<<endl;
	for(w=physical_block;w<COUNT;w++)
	{
		optimal(opt[w]);
	}
	showqyl();
	system("pause");
}
void showqyl()
{//这个代码,就是我刚才说的默认为16进制,害得我必须加上dec(10进制输出)
	cout<<"FIFO"<<"缺页率:"<<dec<<fifo+physical_block<<"/"<<dec<<COUNT<<endl;
	cout<<"LRU"<<"缺页率:"<<dec<<lru+physical_block<<"/"<<dec<<COUNT<<endl;
	cout<<"optimal"<<"缺页率"<<dec<<opti+physical_block<<"/"<<dec<<COUNT<<endl;
}
int  call_in()//位视图是8*8的
{
	int loc;
	for(int h=2;h<8;h++)
		for(int lie=0;lie<8;lie++)
		{
			if(m[h][lie]==0)
			{
				loc=(((8*h)+lie)+1);
				cout<<dec<<loc<<"号内存可以分配"<<endl;
				m[h][lie]=1;
				h=8;
				break;

			}
		}
		showwst();
		return loc;
}
void Inite()
{

	int h=2;
	for(int i=0;i<2;i++)//给最开始的前2行赋值为1,系统区
	{
		for(int j=0;j<8;j++)
		{
			m[i][j]=1;
		}
	}
	do{
		int a[32];
		int i=0;
		long num;
		num=rand()%128;//我在想各种方式变成2进制,什么atoi  itoa  各应死了,都不如自己写一个进制转换
		while(num>=1)//算出2进制数
		{
		  a[i]=num%2;
		  num=num/2;
		  i++;
		}//不足8位在前面补0
		if(i<8)
		{
			for(int j=i;j<=7;j++)
			{
				a[j]=0;
			}
		}		for(i=7;i>=0;i--)
		{
		  m[h][i]=a[i];
		}
		h++;
	}while(h<8);

	for(int h=0;h<8;h++)//行
	{	
		for(int l=0;l<8;l++)//列
		{
			cout<<m[h][l];
		}
		cout<<endl;
	}
}void FIFO(int page_no)
{
	int a=0;
	for(vector<int>::iterator  it = stack.begin();it!=stack.end();++it)
	{
		if(page_no==*it)
		{
			cout<<"命中"<<endl;
			cout<<"物理地址"<<endl<<hex<<pt[page_no].physicalblock_No*1024*page_size+PageAdd<<endl;
			a=1;
			break;
		}
	}
	if(a==0)
	{
		fifo++;
		vector<int>::iterator  it = stack.begin();
		pt[page_no].physicalblock_No=pt[*it].physicalblock_No;
		cout<<"物理地址"<<endl;
		cout<<hex<<pt[page_no].physicalblock_No*page_size*1024+PageAdd<<endl;
		stack.erase(it);
		stack.push_back(page_no);
		pt[page_no].state=0;
	}
	showstack();
}
void showstack()
{

	for(int i=stack.size()-1;i>=0;i--)
	{
		cout<<stack[i]<<endl;
	}
	cout<<endl;}
void showstack2()
{

	for(int i=stack2.size()-1;i>=0;i--)
	{
		cout<<stack2[i]<<endl;
	}
	cout<<endl;
}
void showstack3()
{
	for(int i=stack3.size()-1;i>=0;i--)
	{
		cout<<stack3[i]<<endl;
	}
	cout<<endl;
}void LRU(int page_no)
{
	int a=0;
	for(vector<int>::iterator  it = stack2.begin();it!=stack2.end();++it)
	{
		if(page_no==*it)
		{

			cout<<"命中"<<endl;
			cout<<"物理地址"<<endl<<hex<<pt[page_no].physicalblock_No*1024*page_size+PageAdd<<endl;
			vector<int>::iterator  it = stack2.begin();
			stack2.erase(it);
			stack2.push_back(page_no);
			a=1;
			break;
		}
	}
	if(a==0)
	{
		lru++;
		vector<int>::iterator  it = stack2.begin();
		pt[page_no].physicalblock_No=pt[*it].physicalblock_No;
		cout<<"物理地址"<<endl;
		cout<<hex<<pt[page_no].physicalblock_No*page_size*1024+PageAdd<<endl;		stack2.erase(it);
		stack2.push_back(page_no);

	}
	showstack2();
}
void showwst()
{
	for(int h=0;h<8;h++)//行
	{	
		for(int l=0;l<8;l++)//列
		{
			cout<<m[h][l];
		}
		cout<<endl;
	}
}void optimal(int pageno)
{
	int j=0;int a[25];int m=0;int flag=0;
	for(int i=0;i<physical_block;i++)
	{
		if(stack3[i]==pageno)
		{
			cout<<"命中"<<endl;
			cout<<"物理地址"<<endl<<hex<<pt3[pageno].physicalblock_No3*1024*page_size+PageAdd<<endl;
			m=1;
			break;		}
	}
	if(m==0)
	{
		int p;
		opti++;//缺页次数
		while(j<physical_block)
		{
			for(p=w+1;p<h;p++)//w为当前缺页位置位置的下一个
			{
				if(stack3[j]==opt[p])//2==2
				{
//,a这个数组存的是页面是在第几次出现的,a[2]=9 表示2页在第9个出现的,a[6]=8;代表6这个页面是在第8次出现的,那么淘汰2这个页面
//写到这里我忽然想到了一个排序,计数排序,我不知道我为何会联想到这个伟大的算法
				}
			}
			if(p==h)
			{
				//此页面以后都不会被使用
				pt3[opt[w]].physicalblock_No3=pt3[stack3[j]].physicalblock_No3;
				stack3[j]=opt[w];

				cout<<"物理地址"<<endl;
				cout<<hex<<pt3[opt[w]].physicalblock_No3*page_size*1024+PageAdd<<endl;
				flag=1;
				j=physical_block;			}
			j++;
		}
		if(flag==0)
		{
			int max=0;int out;//要淘汰的页号
			for(int i=0;i<20;i++)
			{
				if(a[i]>max)
				{
					out=i;
					max=a[i];
				}
			}
			for(int i=0;i<physical_block;i++)
			{
				if(stack3[i]==out)
				{
					pt3[pageno].physicalblock_No3=pt3[out].physicalblock_No3;
					cout<<"物理地址"<<endl;
					cout<<hex<<pt3[pageno].physicalblock_No3*page_size*1024+PageAdd<<endl;
					stack3[i]=pageno;
				}
			}
		}
	}
	showstack3();
}