操作系统 实验三: 存储管理

实验目的及要求:

(1)存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。

(2)本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。

3)设计一个虚拟存储方案,并使用下述算法计算访问命中率:

① 最近最少使用算法LRU;

② 最佳淘汰算法OPT;

其中命中率=1-(缺页次数/页地址流长度)

实验内容

(1)设计一个请求页式存储管理方案。

(2)编写模拟程序实现之。要求计算并输出下述各种算法在不同内存容量下的命中率:

①最近最久未使用算法LRU:先淘汰最长时间未使用的页;

②最佳淘汰(置换)算法OPT:先淘汰最不常用的页(以后永不使用的, 或许是在未来最长时间内不再被访问的页面)。

#include"stdio.h"
#include"malloc.h"  /*或#include"alloc.h"*/
#define N 16
#define num 5  /*进程分配物理块数目*/
int A[N]={1,2,3,4,5,6,7,8,5,2,3,2,7,8,1,4};  /*页面号引用串*/
typedef struct page    
{ int address;           /*页面号*/
  struct page *next;      
  }page;
struct page *head,*run,*rear;
void jccreat()   /*给进程分配物理块,初始时内存物理块为空,以后运行时调入*/
{
 int i=1;
 page *p,*q;
 head=(page *)malloc(sizeof(page));
 p=head;
 for(i=1;i<=num;i++) 
 {q=(page *)malloc(sizeof(page));
  p->next=q;
  q->address=0;
  q->next=NULL;
  p=q; }
  rear=p;}
int search(int n) /*在分配的内存物理块中查找n号页面*/
{
  page *p;
  int i=0;
  p=head;
  while(p->next)
  {
   if(p->next->address==n)
   {
   printf("Get it at the page %d\n",i+1);
   run=p;
   return 1;} /*找到,返回1*/ 
   p=p->next;
   i++;
  }
return 0;   /*未找到,返回0*/ 
}
 
void changeOPT(int n,int position) /*OPT页面置换算法*/
{
  //定义需要的变量;
  //先查找空闲物理块,若找到,flag=0;否则,flag=1
  //若flag=0,直接把要访问的页装入找到的空闲物理块
  //若flag=1,计算内存中每个页面要访问的“距离”
  //选择“距离”最远的,换入。
 	int i,flag;
	int total=0;
	int distance[num];
	int MAX;
	int order=0;
	page *p,*q;
	p=head->next;
	q=head->next;
	for(i=0;i<num;i++)
	{
		distance[i]=100;
	}
	i=0;
	while(p)//判断链表是否填满
	{
		if(p->address==-1)
		{
			flag=0;
			break;
		}
		p=p->next;
		i++;
	}
	if(!flag)//链表没有填满
	{
		p->address=n;
		printf("Change the page %d\n",i+1);
	}
	else//链表填满啦
	{
		while(q)//计算距离
		{
			for(i=position+1;i<N;i++)
			{
				if(q->address==A[i])
				{
					distance[total]=i-position;
					break;
				}
			}
			total++;
			q=q->next;
		}
		MAX=distance[0];
		for(i=0;i<num;i++)
		{
			if(distance[i]>MAX)
			{
				MAX=distance[i];
				order=i;//记录要替换的页面的位置
			}
		}
		printf("Change the page %d\n",order+1);
		i=0;
		p=head->next;
		while(p)//页面替换
		{
			if(i==order)
			{
				p->address=n;
			}
			i++;
			p=p->next;
		}
	}
}
 
 
void changeLRU(int n) /*LRU页面置换算法*/
{
  //查找空闲物理块,若找到,直接调入;
  //如果内存没有空闲物理块,选择链表的第一个物理块,进行置换。
	int i=0;
	int flag=1;
	page *p,*delect;
	p=head->next;
 
	while(p)
	{
		if(p->address==0)
		{
			flag=0;
			p->address=n;
			printf("Change the page %d\n",i+1);
			break;
		}
		p=p->next;
		i++;
	}
	if(flag)
	{
		delect=head->next;
		head->next=delect->next;
		printf("Delete from the head,and add new to the end.\n");
		delect->address=n;
		rear->next=delect;
		rear=delect;
		rear->next=NULL;
	}
}
 
float OPT() /*求OPT页面置换算法的命中率*/
{
 int i;
 int lose=0;
 float losef;
 float percent;
 for(i=0;i<N;i++)
 {
  if(search(A[i])==0)  
  {
    lose++;
    changeOPT(A[i],i);
   }
 }
 losef=lose; 
 percent=1-(losef/N);
 return percent;
}
 float LRU()  /*求LRU页面置换算法的命中率*/
{
 int i;
 int lose=0;
 float losef;/*缺页率*/
 float percent;/*命中率*/
 page *p;
 for(i=0;i<N;i++)
 {
  if(search(A[i])==0)
  {
    lose++;
    changeLRU(A[i]);
  }
  else 
   {
    p=run->next;
    run->next=p->next;
    rear->next=p;
    rear=p;
    rear->next=NULL;
    printf("Move it to end of queue.\n");
   }
 }
   losef=lose; 
   percent=1-(losef/N);
   return percent;
} 
 
void main()  /*主函数部分*/
{float percent; 
  int choice;
  printf("Select the arithmetic:\n(1)OPT\n(2)LRU\nyour choice is:");
  scanf("%d",&choice);/*选择页面置换算法*/
  jccreat();               /*创建进程物理块链表*/
  if(choice==1)           /*采用OPT算法置换*/
  {percent=OPT();        /*计算OPT时的命中率*/
  printf("The percent of OPT is %f\n",percent);}
  else if(choice==2)      /*采用LRU算法置换*/
  {percent=LRU();       /*计算LRU时的命中率*/
   printf("The percent of LRU is %f\n",percent);}
  else printf("Your choice is invalid.");
  //getch();
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
请求页式存储管理是一种常用的内存管理方式。在这个方案中,内存被分成大小相等的块,每个块称为一页。每个进程被分成大小相等的块,每个块称为一个页面。当一个进程需要访问一个页面时,如果该页面已经在内存中,则直接访问;否则就产生一个缺页中断,操作系统将该页面从磁盘读入内存中,并将内存中的某一页替换出去。 下面是一个请求页式存储管理的模拟程序,可以实现FIFO和LRU两种页面置换算法,并计算缺页率。假设系统有4个物理块,要运行的进程有10个页面。 ```python import queue class Page: def __init__(self, page_id): self.page_id = page_id self.last_access_time = 0 class Memory: def __init__(self, num_frames): self.num_frames = num_frames self.frames = [None] * num_frames def find_page(self, page_id): for i in range(self.num_frames): if self.frames[i] and self.frames[i].page_id == page_id: return i return -1 def load_page(self, page, index): self.frames[index] = page class Pager: def __init__(self, memory): self.memory = memory def choose_victim(self): pass class FIFOPager(Pager): def __init__(self, memory): super().__init__(memory) self.next_frame = 0 def choose_victim(self): victim = self.next_frame self.next_frame = (self.next_frame + 1) % self.memory.num_frames return victim class LRUPager(Pager): def __init__(self, memory): super().__init__(memory) self.page_access_time = [0] * len(memory.frames) def choose_victim(self): victim = 0 for i in range(1, self.memory.num_frames): if self.page_access_time[i] < self.page_access_time[victim]: victim = i return victim class Simulator: def __init__(self, num_frames, pager): self.num_frames = num_frames self.pager = pager self.memory = Memory(num_frames) self.page_table = {} self.access_sequence = [] self.num_page_faults = 0 def access_page(self, page_id): self.access_sequence.append(page_id) if page_id in self.page_table: index = self.memory.find_page(page_id) self.page_table[page_id].last_access_time = len(self.access_sequence) return index else: self.num_page_faults += 1 if len(self.page_table) < self.num_frames: page = Page(page_id) index = len(self.page_table) self.page_table[page_id] = page self.memory.load_page(page, index) else: victim = self.pager.choose_victim() page_id_to_remove = self.memory.frames[victim].page_id del self.page_table[page_id_to_remove] page = Page(page_id) self.page_table[page_id] = page self.memory.load_page(page, victim) return victim def run(self, page_sequence): for page_id in page_sequence: self.access_page(page_id) return self.num_page_faults / len(page_sequence) if __name__ == '__main__': num_frames = 4 page_sequence = [1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5] pager_choice = input("Choose pager (FIFO/LRU): ") if pager_choice == "FIFO": pager = FIFOPager(Memory(num_frames)) elif pager_choice == "LRU": pager = LRUPager(Memory(num_frames)) else: print("Invalid choice") exit() simulator = Simulator(num_frames, pager) page_fault_rate = simulator.run(page_sequence) print("Page fault rate: %.2f%%" % (page_fault_rate * 100)) ``` 在模拟程序中,我们定义了三个类:`Page`表示一个页面,`Memory`表示内存,`Pager`表示页面置换算法。我们还定义了两个具体的页面置换算法:`FIFOPager`是先进先出算法,`LRUPager`是最近最久未使用算法。在`Simulator`类中,我们定义了`access_page`方法来处理页面请求,`run`方法来运行整个模拟程序并计算缺页率。 下面是一个示例运行结果: ``` Choose pager (FIFO/LRU): FIFO Page fault rate: 58.33% ``` 在这个示例中,我们选择了先进先出算法,页面请求序列为`[1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5]`,内存大小为4个页面。程序输出了缺页率为58.33%。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值