现在的位置: 首页 > 综合 > 正文

操作系统 实验二 请求分页存储器管理

2012年11月26日 ⁄ 综合 ⁄ 共 4926字 ⁄ 字号 评论关闭

实验目的:

实现分页式存储地址转换过程,在此基础上实现请求分页的地址转换。实现请求分页式地址转换中出现的缺页现象中,用到的FIFO、LRU、OPT置换算法

实现方法:

用一张位示图,来模拟内存的分配情况,利用随机数产生一组0和1的数对应内存的使用情况。

利用结构体数组将页表和内存块封装。

实现过程:

#include<stdio.h>
#include<stdlib.h>
#include<iostream.h>
#include<time.h>
struct Page
{
	int kuai;
	int stage;
}FPage[1000],LPage[1000];

struct Memory
{
	int num;
	int page;
}FMemory[1000],LMemory[1000],OMemory[1000];

int PageLength;			/*页表长度*/
int Memsize;			/*内存块数*/
int FAbsent,LAbsent,OAbsent,visit;			/*FIFO中的缺页次数	LRU中的缺页次数		访问内存次数	*/
int Logical;			/*逻辑地址*/
int Pagenumber,Pageaddr;/*页号	页内地址*/
int Physical;		/*物理地址*/
int PageSize;		/*块的大小*/
int Freemem;		/*空闲内存*/

int G[8][8];

int opt[10000];		int oth=0;
int temp[1000];

void GShow()
{
	int i,j;
	printf("位式图:\n");
	for(i=0;i<8;i++)
	{
		printf("\t");
		for(j=0;j<8;j++)		
			printf("%d ",G[i][j]);
		printf("\n");
	}
}


void init()					/*初始化*/
{
	srand((unsigned)time(NULL));
	int i,j;
	for(i=0;i<8;i++)
		G[0][i]=1;
	for(i=1;i<8;i++)
	{
		for(j=0;j<8;j++)
			G[i][j]=rand()%2;
	}	
	
	for(i=0;i<PageLength;i++)
	{
		FPage[i].kuai=-1;		FPage[i].stage=0;	
		LPage[i].kuai=-1;		LPage[i].stage=0;
	}
	for(i=0;i<Memsize;i++)
	{
		FMemory[i].page=-1;
	}
	for(i=0;i<Memsize;i++)
	{
		LMemory[i].page=-1;
	}	
	for(i=0;i<Memsize;i++)
	{
		OMemory[i].num=i;
		OMemory[i].page=-1;
	}
	
	FAbsent=LAbsent=visit=0;
}


void Show()
{
	int i;
	
	printf("FPage:\t\t\t\t\tLPage:\n");
	printf("\t页号\t块号\t状态位\t\t\t页号\t块号\t状态位\n");
	for(i=0;i<PageLength;i++)
	{
		printf("\t%d\t",i);		
		if(FPage[i].kuai==-1)
			printf(" \t");
		else
			printf("%d\t",FPage[i].kuai);
		printf("%d",FPage[i].stage);
		printf("\t\t\t%d\t",i);
		if(LPage[i].kuai==-1)
			printf(" \t");
		else
			printf("%d\t",LPage[i].kuai);
		printf("%d\n",LPage[i].stage);
	}
	printf("\nFMemory:\t\t\t\tLMemory:\n");
	printf("\t块号\t页号\t\t\t\t块号\t\t页号\n");
	for(i=Memsize-1;i>=0;i--)
	{
		printf("\t%d\t",i);
		if(FMemory[i].page==-1)
			printf(" \t\t");
		else
			printf("%d\t\t",FMemory[i].page);
		printf("\t\t%d\t",i);
		if(LMemory[i].page==-1)
			printf("\n");
		else
			printf("\t%d\n",LMemory[i].page);
	}
	printf("Logical: %d\n",Logical);
	printf("Count: %d	%d\n",Pagenumber,Pageaddr);
	printf("Physical: %d\n",Physical);
	printf("PageSize: %d\n",PageSize);
	printf("Visit: %d\n",visit);
	printf("FAbsent: %d		LAbsent: %d\n",FAbsent,LAbsent);
	printf("FRate: %.2f%%		LRate: %.2f%%\n",(double)FAbsent*100/(double)visit,(double)LAbsent*100/(double)visit);
}


void FIFO()				/*FIFO算法*/
{
	int i;
	int m,n;
	
	
	if(FPage[Pagenumber].stage==1)		/*命中*/
		;
	else				/*缺页*/
	{
		FAbsent++;
		FPage[Pagenumber].stage=1;
		
		for(i=0;i<Memsize;i++)
		{
			if(FMemory[i].page==-1)
			{
				for(m=1;m<8;m++)
				{
					for(n=0;n<8;n++)
						if(G[m][n]==0)
						{
							break;
						}
						if(n<8)
							break;
				}
				Freemem=(m-1)*8+n;
				FMemory[i].page=Pagenumber;
				FPage[Pagenumber].kuai=Freemem;
				
				break;
			}
		}
		if(i==Memsize)
		{
			FPage[Pagenumber].kuai=FPage[FMemory[0].page].kuai;
			FPage[FMemory[0].page].kuai=-1;
			FPage[FMemory[0].page].stage=0;
			for(i=0;i<Memsize-1;i++)
				FMemory[i].page=FMemory[i+1].page;
			FMemory[i].page=Pagenumber;
		}
	}
	
}
void LRU()					/*LRU算法*/
{
	int i,j,m,n,l;

	//bool flag=true;
	
	for(l=0;l<Memsize;l++)
		if(LMemory[l].page==-1)
			break;
	
	if(LPage[Pagenumber].stage==1)/*命中*/
	{
		for(i=0;i<l;i++)
		{
			if(LMemory[i].page==Pagenumber)
			{
				for(j=i;j<l-1;j++)
				{
					LMemory[j].page=LMemory[j+1].page;
				}
				LMemory[j].page=Pagenumber;
				break;
			}
		}
	}
	else			/*没命中*/
	{
		LAbsent++;
		LPage[Pagenumber].stage=1;

		if(l<Memsize)		//问题出在这里,l++之前需要判断一下 如果l<memsize说明有空闲块,则l++ ,否则块已经满了,l不能++ ... 
			l++;
		for(i=0;i<l;i++)
		{
			if(LMemory[i].page==-1)
			{
				for(m=1;m<8;m++)
				{
					for(n=0;n<8;n++)
						if(G[m][n]==0)
						{
							G[m][n]=1;
							break;
						}
						if(n<8)
							break;
				}
				Freemem=(m-1)*8+n;
				LMemory[i].page=Pagenumber;
				LPage[Pagenumber].kuai=Freemem;
				for(j=i;j<l-1;j++)
				{
					LMemory[j].page=LMemory[j+1].page;
				}
				LMemory[j].page=Pagenumber;
				break;
			}
		}
		if(i==l)
		{
			LPage[LMemory[0].page].stage=0;
			LPage[Pagenumber].kuai=LPage[LMemory[0].page].kuai;
			LPage[LMemory[0].page].kuai=-1;
			for(j=0;j<l-1;j++)
				LMemory[j].page=LMemory[j+1].page;
			LMemory[j].page=Pagenumber;
		}
	}
}

void OPTshow()
{
	int i;
	printf("\t");
	for(i=Memsize-1;i>=0;i--)
	{
		if(OMemory[i].page==-1)
			printf("  ");
		else
			printf(" %d",OMemory[i].page);
	}
	printf("\n");
}

void OPT()
{
	printf("\nOPTMemory:\n");
	printf("\t 2 1 0\n\n");
	int i,j,k,l,m,n;
	int count=0;
	for(i=0;i<oth;i++)
	{
		for(j=0;j<Memsize;j++)
		{
			if(OMemory[j].page==opt[i])
				break;
		}
		if(j<Memsize)
			;
		else
		{
			for(j=0;j<Memsize;j++)
			{
				if(OMemory[j].page==-1)			/*如果此时内存没满还有空缺 就直接将页号写进去*/
				{
					OMemory[j].page=opt[i];
					break;
				}
			}
			if(j==Memsize)				/*需要发生置换*/
			{
				OAbsent++;
				for(n=0;n<Memsize;n++)
					temp[n]=0;	
				
				for(k=i+1;k<oth;k++)
				{	
					for(l=0;l<Memsize;l++)
					{
						if(OMemory[l].page==opt[k])
						{
							temp[l]++;
							break;
						}
					}
					count=0;
					for(m=0;m<Memsize;m++)
					{
						if(temp[m]==0)
							count++;
					}
					if(count>1&&k<oth-1)
						;
					else
					{
						for(m=0;m<Memsize;m++)
							if(temp[m]==0)
							{
								OMemory[m].page=opt[i];
								break;
							}
					}
				}
			}
		}
		OPTshow();		
	}
	printf("OAbsent: %d\n",OAbsent);
	printf("ORate: %.2f%%\n",(double)OAbsent*100/(double)visit);
	
}

void cometrue()
{
	printf("输入页表长度(页):");
	scanf("%d",&PageLength);
	printf("输入内存块数(块):");
	scanf("%d",&Memsize);
	printf("输入页面大小(kb):");
	scanf("%d",&PageSize);
	init();
	while(printf("输入逻辑地址(10进制): ")&&scanf("%d",&Logical))
	{
		if(Logical!=-1)
		{
			Pagenumber=Logical/(PageSize*1024);
			Pageaddr=Logical%(PageSize*1024);
			if(Pagenumber>=PageLength)
			{
				printf("越界中断......!\n");
				continue;
			}
			opt[oth++]=Pagenumber;
			GShow();
			FIFO();
			LRU();
			
			Physical=Freemem*PageSize*1024+Pageaddr;
			visit++;
			
			Show();
		}
		else if(Logical==-1)
		{
			int i;
			printf("页号访问序列:\n");
			for(i=0;i<oth;i++)
				printf("%d  ",opt[i]);
			printf("\n");
			OPT();
			break;
		}
	}
}

int main()
{
	cometrue();
	return 0;
}

抱歉!评论已关闭.