页面置换算法代码实现完整版
(完整word版)页面置换算法OPT+FIFO+LRU+clock
#include<iostream>#include<fstream>using namespace std;#define BlockSize 10#define PageSize 100int page[PageSize]; //页面数组存放页面int block[BlockSize]; //物理块数组int result[PageSize][BlockSize]; //存放页面和物理块二维数组int pSize = 0; //用户使用页面数int bSize = 0; //用户使用物理块数int blockFlag[BlockSize]; //用于LRU与最佳置换算法中,辅助判断该换出的页面int noPageCount = 0; //缺页次数//输入数据void inputData(){cout<<endl<<"请输入物理块数(1<=bSize<="<<BlockSize<<')'<<endl;cin>>bSize;cout<<"请输入页面数(1<=pSize<="<<PageSize<<')'<<endl;cin>>pSize;while(bSize<=0||bSize>BlockSize||pSize<=0||pSize>PageSize){//判断用户输入是否在范围内cout<<"输入范围错误,请重新输入:"<<endl;cout<<"请输入物理块数(1<=F<="<<BlockSize<<')';cin>>bSize;cout<<endl<<"请输入页面数(1<=p<="<<PageSize<<')';cin>>pSize;}cout<<"请输入页面走向"<<endl;for(int i = 0;i <pSize;i++)cin>>page[i];}//初始化page数组void initPage(){for(int i = 0;i<PageSize;i++)page[i] = -1;}//初始化block与result数组void initBlockResult(){int i = 0;for(i = 0;i<BlockSize;i++)block[i] = -1;for(i = 0;i < PageSize;i++)for(int j = 0; j < BlockSize;j++)result[i][j] = -1;}//查找物理块中是否存在要调用的页面int Exist(int i){for(int j = 0;j < bSize;j++)if(block[j] == i)return j;return -1;}//显示结果void display(int noPageCount){for(int i =0 ;i < pSize;i++){cout<<" "<<page[i]<<" ";for(int j = 0;j < bSize;j++){if(result[i][j] == -1) break;else cout<<'['<<result[i][j]<<']'<<' ';}cout<<endl;}cout<<"____________________________________"<<endl;cout<<endl<<"缺页次数:"<<noPageCount<<endl;cout<<"缺页率:"<<((double)noPageCount/pSize)*100<<'%'<<endl;cout<<"===================================="<<endl;}//最佳置换算法OPTvoid OPT(){int i = 0,j = 0;int position = 0,noPageCount = 0;int pageFlag = 0,resultFlag = 0; //页面标记(下标)指向下一个页面,结果标记表示结果的行,即result数组的行标for(i = 0;i < BlockSize;i++)blockFlag[i] = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1) //判断页面是否已经存在resultFlag++;else{if(position < bSize) //判断有无空闲物理块{ //若有则将页面放入空闲块block[position] = page[pageFlag];position++;noPageCount++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{for(i = 0;i < bSize;i++){for(j = pageFlag+1;j < pSize;j++){if(block[i] == page[j]){blockFlag[i] = j;break;}}if(j == pSize) blockFlag[i] = 999;}int optPos = 0,max = blockFlag[0];for(int i = 0;i < bSize;i++)if(max < blockFlag[i]){max = blockFlag[i];optPos = i;}block[optPos] = page[pageFlag];noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;}}pageFlag++;}cout<<endl<<"最佳置换算法:"<<endl;display(noPageCount);return;}//先进先出页面置换算法FIFOvoid FIFO(){int blockFlag = 0,pageFlag = 0,resultFlag = 0; //物理块标记,确定该换出的物理块下标int i = 0,j = 0,noPageCount = 0;int position = 0; //指示物理块,查找有无空闲while (pageFlag < pSize){if(Exist(page[pageFlag]) != -1)resultFlag++;else{if(position < bSize){block[position] = page[pageFlag];position++;noPageCount++;for(i = 0;i <= position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{block[blockFlag] = page[pageFlag]; //blockFlag指示要换出的页面noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;blockFlag++;blockFlag = blockFlag % bSize;}}pageFlag++;}cout<<endl<<"先进先出页面置换算法FIFO:"<<endl;display(noPageCount);return;}//最近最久未用算法LRUvoid LRU(){int i = 0,noPageCount = 0;int pageFlag = 0,resultFlag = 0,position = 0;for(i = 0;i < BlockSize;i++) //初始化时间记录数组blockFlag[i] = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1){ //判断页面是否已经在主存中resultFlag++;blockFlag[Exist(page[pageFlag])] = 0; //若在则将时间记录数组对应位置为0 }else{if(position < bSize){block[position] = page[pageFlag];blockFlag[position] = 0;position++;noPageCount++;for(i = 0;i <= position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{int last = 0,min = blockFlag[0];for(int i = 0;i < bSize;i++)if(min < blockFlag[i]){min = blockFlag[i];last = i;}block[last] = page[pageFlag]; //置换最久未用页面blockFlag[last] = 0;noPageCount++;for(i = 0;i < bSize;i++)result[resultFlag][i] = block[i];resultFlag++;}}for(i = 0;i < bSize;i++)blockFlag[i]++;pageFlag++;}cout<<endl<<"最近最久未用算法LRU:"<<endl;display(noPageCount);return;}//时钟(clock)置换算法void clock(){int i = 0,position = 0,noPageCount = 0;bool boolBlockFlag[BlockSize];int flag = 0; //访问位循环标记int pageFlag = 0,resultFlag = 0;while(pageFlag < pSize){if(Exist(page[pageFlag]) != -1){resultFlag++;boolBlockFlag[Exist(page[pageFlag])] = true;}else{if(position < bSize){block[position] = page[pageFlag];noPageCount++;boolBlockFlag[position] = true;position++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}else{while(true){ //无限循环,找出访问位为false 的页面if(boolBlockFlag[flag] == false) break;boolBlockFlag[flag] = false; //若为true,置为falseflag++;flag = flag%bSize;}block[flag] = page[pageFlag];boolBlockFlag[flag] = true;flag++;flag = flag%bSize;noPageCount++;for(i = 0;i < position;i++)result[resultFlag][i] = block[i];resultFlag++;}}pageFlag++;}cout<<endl<<"时钟(clock)置换算法:"<<endl;display(noPageCount);return;}int main(){initPage();int func;while(func!=5){cout<<"请选择所需要的功能:"<<endl;cout<<"0.输入数据"<<endl;cout<<"1.最佳(optimal)置换算法"<<endl;cout<<"2.先进先出(FIFO)置换算法"<<endl;cout<<"3.最近最久未用(LRU)置换算法"<<endl;cout<<"4.时钟(clock)置换算法"<<endl;cout<<"5.退出"<<endl;switch(func){case 0:inputData();break;case 1:initBlockResult();OPT();break;case 2:initBlockResult();FIFO();break;case 3:initBlockResult();LRU();break;case 4:initBlockResult();clock();break;case 5:break;}cout<<"请选择功能:";cin>>func;system("cls");}return 0;}。
页面置换算法程序代码
//最近最少使用调度算法(LRU)
void LRU()
{
int absence=0;
int i,j;
int flag;
cout<<endl<<"----------------------------------------------------"<<endl;
pages[i].hit=0;
}
}
//读入页访问流
void readData()
{
FILE *fp;
char fname[20];
int i;
cout<<"请输入页面流文件名:";
cin>>fname;
if((fp=fopen(fname,"r"))==NULL)
{
//缺页处理
if(absence>=MAXQUEUE)
{cout<<pages[0].loaded<<" "; }// pages[0]是队列头
for(j=0;j<MAXQUEUE-1;j++)
{
pages[j]=pages[j+1];
}
pages[MAXQUEUE-1].loaded=queue[i];
{
cout<<"错误,文件打不开,请检查文件名";
}
else
{
while(!feof(fp))
{
fscanf(fp,"%d ",&queue[quantity]);
matlab实现fifo页面置换算法 -回复
matlab实现fifo页面置换算法-回复如何使用MATLAB实现FIFO页面置换算法FIFO页面置换算法,也称为先进先出页面置换算法,是最简单且最常见的页面置换算法之一。
该算法按照页面进入内存的顺序进行页面置换,即最早进入内存的页面最先被置换出去。
在本文中,我将逐步介绍如何使用MATLAB实现FIFO页面置换算法。
让我们一起开始吧!步骤1:导入所需模块和数据首先,我们需要导入MATLAB中所需的模块和数据。
在这个例子中,我们假设我们有一个页面引用序列,即一个包含许多页面的数组。
我们还需要定义内存的大小,即能容纳的页面数量。
导入页面引用序列page_references = [2, 3, 4, 2, 1, 5, 6, 2, 5, 4, 3, 2, 1, 5, 6];定义内存大小(页面数量)memory_size = 3;步骤2:初始化数据结构接下来,我们需要初始化一些数据结构。
我们将使用一个队列来表示内存中的页面,并使用一个集合来保存当前内存中的页面。
初始化一个空队列,用于表示内存中的页面memory_queue = [];初始化一个空集合,用于保存当前内存中的页面memory_set = [];步骤3:遍历页面引用序列现在,我们可以开始遍历页面引用序列,模拟页面的引用过程,并根据FIFO 页面置换算法将页面置换出去。
对于每个页面引用,我们需要执行以下步骤:1. 检查页面是否已经在内存中:如果页面已经在内存中,我们继续执行下一个页面引用。
2. 检查内存是否已满:如果内存已满,我们需要从内存中移除一个页面。
按照FIFO算法的原理,我们需要移除队列中的第一个页面,并从内存集合中删除该页面。
3. 将页面添加到内存中:将页面添加到队列的末尾,并将该页面添加到内存集合中。
以下是以上步骤的MATLAB代码实现:for i = 1:length(page_references)page = page_references(i);检查页面是否已经在内存中if ismember(page, memory_set)continue;end检查内存是否已满if length(memory_queue) == memory_size从队列中移除第一个页面removed_page = memory_queue(1);memory_queue = memory_queue(2:end);从内存集合中删除该页面memory_set = memory_set(memory_set ~=removed_page);end将页面添加到内存中memory_queue = [memory_queue, page];memory_set = [memory_set, page];end步骤4:计算页面置换次数在完成对页面引用序列的遍历后,我们可以计算页面置换的次数。
页面置换算法
#include "windows.h"#include <conio.h>#include <stdlib.h>#include <fstream.h>#include <io.h>#include <string.h>#include <stdio.h>void initialize(); //初始化相关数据结构void createps(); //随机生成访问序列void displayinfo(); //显示当前状态及缺页情况void fifo(); //先进先出算法int findpage(); //查找页面是否在内存void lru(); //最近最久未使用算法int invalidcount = 0; // 缺页次数int vpoint; //页面访问指针int pageframe[10]; // 分配的页框int pagehistory[10]; //记录页框中数据的访问历史int rpoint; //页面替换指针int inpflag; //缺页标志,0为不缺页,1为缺页struct PageInfo //页面信息结构{int serial[100]; // 模拟的最大访问页面数,实际控制在20以上int flag; // 标志位,0表示无页面访问数据int diseffect; // 缺页次数int total_pf; // 分配的页框数int total_pn; // 访问页面序列长度} pf_info;//////////////////////////////////////////////////////////////////////////初始化相关数据结构void initialize(){int i,pf;inpflag=0; //缺页标志,0为不缺页,1为缺页pf_info.diseffect =0; // 缺页次数pf_info.flag =0; // 标志位,0表示无页面访问数据printf("\n请输入要分配的页框数:"); // 自定义分配的页框数scanf("%d",&pf);pf_info.total_pf =pf;for(i=0;i<100;i++) // 清空页面序列{pf_info.serial[i]=-1;}}///////////////////////////////////////////////////////////////////// 随机生成访问序列void createps(void ){int s,i,pn;initialize(); //初始化相关数据结构printf("\n请输入要随机生成访问序列的长度:"); //自定义随机生成访问序列的长度scanf("%d",&pn);srand(rand()); //初始化随机数队列的"种子"s=((float) rand() / 32767) * 50 + pn; // 随机产生页面序列长度pf_info.total_pn = s;for(i=0;i<s;i++) //产生随机访问序列{pf_info.serial[i]=((float) rand() / 32767) * 16 ; //随机数的大小在0-15之间}}////////////////////////////////////////////////////////////////////////// 显示当前状态及缺页情况void displayinfo(void){int i,n;if(vpoint==0){printf("\n=============页面访问序列=============\n");for(i=0; i<pf_info.total_pn; i++){printf("%4d",pf_info.serial[i]);if ((i+1) % 10 ==0) printf("\n"); //每行显示10个}printf("\n======================================\n");}printf("访问%3d : 内存<",pf_info.serial[vpoint]);for(n=0;n<pf_info.total_pf;n++) // 页框信息{if (pageframe[n] >=0)printf("%3d",pageframe[n]);elseprintf(" ");}printf(" >");if(inpflag==1) //缺页标志,0为不缺页,1为缺页{printf(" ==>缺页");printf("缺页率%3.1f",(float)(pf_info.diseffect)*100.00/vpoint);}printf("\n");}////////////////////////////////////////////////////////////////////////// 查找页面是否在内存,1为在内存,0为不在即缺页int findpage(int page){int n;for(n=0;n<pf_info.total_pf;n++){pagehistory[n] ++; // 访问历史加1}for(n=0;n<pf_info.total_pf;n++){if (pageframe[n]==page ){inpflag=0 ; //inpflag缺页标志,0为不缺页,1为缺页pagehistory[n]=0; //置访问历史为0return 1;}}inpflag=1; //页面不存在,缺页return 0;}////////////////////////////////////////////////////////////////////////// FIFO页面置换算法void fifo(void){int n,count,pstate;rpoint=0; // 页面替换指针初始化为0invalidcount = 0; // 缺页数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满是所有的页框for(n=0;n<pf_info.total_pf;n++) // 清除页框信息{pageframe[n]=-1;}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0) // 页不存在则置换页面{pageframe[rpoint]=pf_info.serial[vpoint];rpoint=(rpoint+1) % pf_info.total_pf;pf_info.diseffect++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}///////////////////////////////////////////////////////////////////// LRU页面置换算法void lru(void){int n,count,pstate,max;rpoint=0; // 页面替换指针invalidcount = 0; // 缺页次数初始化为0createps(); // 随机生成访问序列count=0; // 是否装满所有的页框for(n=0;n<pf_info.total_pf;n++){pageframe[n]=-1; // 清除页框信息pagehistory[n]=0; // 清除页框历史}inpflag=0; //缺页标志,0为不缺页,1为缺页for(vpoint=0;vpoint<pf_info.total_pn;vpoint++) // 执行算法{pstate=findpage(pf_info.serial[vpoint]); //查找页面是否在内存if(count<pf_info.total_pf) // 开始时不计算缺页{if(pstate==0) // 页不存在则装入页面{pageframe[rpoint]=pf_info.serial[vpoint]; //把要调入的页面放入一个空的页框里rpoint=(rpoint+1) % pf_info.total_pf;count++;}}else // 正常缺页置换{if(pstate==0)// 页不存在则置换页面{max=0;for(n=1;n<pf_info.total_pf;n++){if(pagehistory[n]>pagehistory[max]){max=n;}}rpoint=max;pageframe[rpoint]=pf_info.serial[vpoint];pagehistory[rpoint]=0;pf_info.diseffect++; // 缺页次数加1}}Sleep(10);displayinfo(); // 显示当前状态} // 置换算法循环结束_getch();return;}///////////////////////////////////////////////////////////////////// 主函数int main(){char ch;system("cls") ;while ( true ){//printf("若要执行FIFO页面置算法请按"1"\n");//printf("若要执行LRU 页面置算法请按"2" \n");//printf("若要退出请按"3"\n");printf("*******************************************\n");printf( "Enter your choice (1 or 2 or 3): ");do{ //如果输入信息不正确,继续输入ch = (char)_getch() ;}while(ch != '1' && ch != '2'&& ch != '3');printf("\n\n你按的是:%c ,现在为你执行对应操作。
页面置换算法(FIFO算法,LRU算法)
实验四页面置换算法一、实验流程图二、实验程序#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define null 0#define len sizeof(struct page)struct page{ int num;int tag;struct page *next;};struct page *create(int n) /*建立分配的内存空间,并初始化,返回头结点*/{int count=1;struct page *p1,*p2,*head;head=p2=p1=(struct page *)malloc(len); //开辟一个新的单元,并将malloc返回的指针转换为结构体类型的指针p1->tag=-1;p1->num=-1;while(count<n){count++;p1=(struct page *)malloc(len);p1->tag=-1;p1->num=-1;p2->next=p1;p2=p1;}p2->next=null;return(head);}void FIFO(int array[],int n){int *p;struct page *cp,*dp,*head,*new1;int count=0;head=create(n);p=array;while(*p!=-1){ cp=dp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if (cp->num==*p) printf(" ! " );else{ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){cp->num=*p;printf(" * ");}else{new1=(struct page*)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}void LRU(int array[],int n){int count=0,*p=array;struct page *head,*cp,*dp,*rp,*new1,*endp;head=create(n);while(*p!=-1){cp=dp=rp=endp=head;for(;endp->next!=null;) endp=endp->next;for(;cp->num!=*p&&cp->next!=null;){rp=cp;cp=cp->next;}if(cp->num==*p){printf(" ! ");if(cp->next!=null){if(cp!=head)rp->next=cp->next;else head=head->next;}endp->next=cp;cp->next=null;}else{count++;cp=rp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;{printf(" * ");cp->num=*p;cp->tag=0;}else{new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}}p++;}printf("\nQueye Zongshu : %d \n",count);}OPT(int array[],int n){int *p,*q,count=0,i;struct page *head,*cp,*dp,*new1;p=array;head=create(n);while(*p!=-1){ cp=head;for(;cp->num!=*p&&cp->next!=null;) cp=cp->next;if(cp->num!=*p){ count++;cp=head;for(;cp->tag!=-1&&cp->next!=null;) cp=cp->next;if(cp->tag==-1){printf(" * ");cp->num=*p;cp->tag=0;}else{ i=1;q=p;q++;cp=head;while(*q!=-1&&i<n){ for(;*q!=cp->num&&cp->next!=null;) cp=cp->next;if(*q==cp->num){cp->tag=1;i++;}q++;cp=head;}if(i==n){for(;cp->tag!=0;) cp=cp->next;printf(" %d ",cp->num);cp->num=*p;}else{ cp=head;for(;cp->tag!=0;) cp=cp->next;if(cp==head){ for(;cp->next!=null;) cp=cp->next;new1=(struct page *)malloc(len);new1->num=*p;new1->tag=0;new1->next=null;cp->next=new1;dp=head;head=head->next;printf(" %d ",dp->num);free(dp);}else{ printf(" %d ",cp->num);cp->num=*p;}}cp=head;for(;cp->next!=null;) {cp->tag=0;cp=cp->next;}cp->tag=0;}}else printf(" ! ");p++;}printf("\nQueye Zongshu : %d \n",count);}main(){FILE *fp;char pt;char str[10];int i,j=0;int page[50],space=0;for(i=0;i<50;i++)page[i]=-1;fp=fopen("page.txt","r+");if(fp==NULL){printf("Cann't open the file\n");exit(0);}i=0;while((pt=fgetc(fp))!=EOF)/*将数字字符串转化成整型-开始*/ {if(pt>='0'&&pt<='9'){str[i]=pt;i++;space=0;}else{if(pt==' '||pt=='\n'){if(space==1) break;else{str[i]='\0';page[j]=atoi(str);if(pt=='\n') break;else{space=1;j++;i=0;}}}}}/*结束*/if(pt==EOF) {str[i]='\0';page[j]=atoi(str);}i=0;while(page[i]!=-1) {printf(" %d ",page[i]);i++;}fclose(fp);printf("\n");printf(" ! : mean no moved \n * : mean have free space \n\n"); printf("FIFO ");FIFO(page,3);printf("\nLRU ");LRU(page,3);printf("\nOPT ");OPT(page,3);}。
lfu页面置换算法代码
lfu页面置换算法代码下面是一个简单的 LFU (Least Frequently Used) 页面置换算法的Python 实现。
这个实现是基于一个字典和一个列表,其中字典存储了每个页面的访问频率,列表存储了所有页面的访问顺序。
```pythonclass LFU:def __init__(self, capacity):self.capacity = capacityself.cache = {}self.order = []self.freq = {}def get(self, key):if key in self.cache:value = self.cache[key]self.order.remove(key)self.order.append(key)self.update_freq(key)return valueelse:return -1def put(self, key, value):if len(self.cache) >= self.capacity:lfu_key = self.order[0]del self.cache[lfu_key]del self.freq[lfu_key]self.order.remove(lfu_key)else:self.order.append(key)self.cache[key] = valueself.update_freq(key)def update_freq(self, key):if key in self.freq:self.freq[key] += 1else:self.freq[key] = 1```在这个实现中,`get` 方法用于获取一个键的值,如果键在缓存中,那么它将被从缓存中移除并添加到访问顺序的末尾,然后更新访问频率。
如果键不在缓存中,那么返回 -1。
`put` 方法用于添加一个新的键值对到缓存中,如果缓存已经满了,那么将删除访问频率最低的键和它的值。
页面置换算法实验(内含完整代码)
实验二存储管理一、实验目的通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
二、实验内容基于一个虚拟存储区和内存工作区,设计下述算法并计算访问命中率。
1、最佳淘汰算法(OPT)2、先进先出的算法(FIFO)3、最近最久未使用算法(LRU)4、简单时钟(钟表)算法(CLOCK)命中率=1-页面失效次数/页地址流(序列)长度三、实验原理简述UNIX中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。
当进程在运行中需要访问某部分程序和数据时,发现其所在页面不在内存,就立即提出请求(向CPU发出缺中断),由系统将其所需页面调入内存。
这种页面调入方式叫请求调页。
为实现请求调页,核心配置了四种数据结构:页表、页帧(框)号、访问位、修改位、有效位、保护位等。
当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。
该程序通过查找页表,得到该页所在外存的物理块号。
如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。
如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。
利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。
整个页面的调入过程对用户是透明的。
四、算法描述本实验的程序设计基本上按照实验内容进行。
即使用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
(1)通过随机数产生一个指令序列,共320条指令。
指令的地址按下述原则生成:A:50%的指令是顺序执行的B:25%的指令是均匀分布在前地址部分C:25%的指令是均匀分布在后地址部分具体的实施方法是:A:在[0,319]的指令地址之间随机选取一起点mB:顺序执行一条指令,即执行地址为m+1的指令C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’D:顺序执行一条指令,其地址为m’+1E:在后地址[m’+2,319]中随机选取一条指令并执行F:重复步骤A-E,直到320次指令(2)将指令序列变换为页地址流设:页面大小为1K;用户内存(页帧)容量为4页~32页;用户虚存容量为32K。
存储管理的页面置换算法
FCFS算法设计说明:按照所要求的产生随机指令序列,存放在order[320]这个数组中。
通过循环产生这些随机指令,每产生一条都要进行下列判断:是否和内存中即mem_volume[4]中存放的页面相同,如果相同则不做任何操作,如果不相同,则产生缺页,相应的缺页次数加一,按照fcfs将最先进入内存的页数淘汰,并将该页写到内存中去。
重复上面的操作直到完成这320条指令。
Fcfs页面置换算法实现代码:#include <stdio.h>#include <stdlib.h>#include <time.h>int main(void){int order[320],mem_volume[4]={100,100,100,100};int l=0,i=0,j,num=0,cx,sign=0,add=0;float value=0,sum=0;srand(time(NULL));for(cx=0;cx<10;cx++){while(i<320){order[i]=rand()%320; //产生随机数放order中for(j=0;j<4;j++)if((order[i]+1)/10==mem_volume[j])sign=1; //通过sign标识判断所调页数是否在内存块中if(sign)sign=0;else{l++;if(mem_volume[3]==100)mem_volume[3]=(order[i]+1)/10;// 保证第一次调入的页面都产生缺页else{mem_volume[num]=(order[i]+1)/10; //将所缺页调入到内存块中num=(num+1)%4; //num值为下次所要置换出去的内存块中对应的页数}}i++;order[i]=rand()%(order[i-1]+2);for(j=0;j<4;j++)if(order[i]/10==mem_volume[j])sign=1;if(sign)sign=0;else {l++;if(mem_volume[2]==100)mem_volume[2]=order[i]/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;}}i++;order[i]=order[i-1]+1;for(j=0;j<4;j++)if(order[i]/10== mem_volume[j])sign=1;if(sign)sign=0;else{l++;if(mem_volume[1]==100)mem_volume[1]=order[i]/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;} }i++;order[i]=rand()%(319-order[i-1]-2)+(order[i-1]+2); for(j=0;j<4;j++)if(order[i]/10==mem_volume[0])sign=1;if(sign)sign=0;else {l++;if(mem_volume[0]==100)mem_volume[0]=(order[i]+1)/10;else{mem_volume[num]=order[i]/10;num=(num+1)%4;} }i++;}value=l/320.0*100;add=add+l;sum=sum+value;}printf("\2***************FCFS页面置换算法*******************\2\n");printf("*******************最后一次指令序列************************");for(i=0;i<320;i++){if(i%10==0)printf("\n");printf("%5d",order[i]);}printf("\n");printf("*****************************************************\n");printf("\t\t十次的平均缺页数为%d\n\t\t十次的平均缺页率为%.3f%%",add/10,sum/10);return 0;}LRU页面置换算法设计说明:这个算法同FCFS算法的不同之处在于,每产生一条随机指令,如果和4个内存块中的某一个页数相同的话,就要对这4个内存块中的页数重新排序,将每次要置换出去的页数放在mem_volume[3]中,这样,在每次产生缺页的时候,都先将所缺页数写入到该内存块,然后再排序,将其放到mem_volume[0]中去。
c语言实现页面置换
#include "stdio.h"#include "stdlib.h"#define true 1#define false 0int wang;/*是否有元素*/int have(int a[],int t){int i=0,j=0;for(j=0;j<4;j++){if(a[j]==t){i=1; /*有元素*/break;}}return i;}/*先进先出页面置换算法*/void FIFO(int num[]){int i,j,k;int a[4]={-1,-1,-1,-1} ;for(i=0,j=0;i<20;i++){if(j<4){if(have(a,num[i])==0) a[j++]=num[i];}else{if(have(a,num[i])==0) {for(j=1;j<4;j++) a[j-1]=a[j]; a[3]=num[i];}}for(k=0;k<4;k++)printf(" %2d",a[k]); printf(" \n");}}/*最近最久未使用*/void LRU(int num[]){int i,j,k,temp;int a[4]={-1,-1,-1,-1} ;for(i=0;i<20;i++){if(i==0)a[0]=num[0];else{for(j=0;j<4;j++){if(a[j]==num[i]) break;}for(k=j;k>0;k--){a[k]=a[k-1];}a[0]=num[i];}for(k=0;k<4;k++)printf(" %2d",a[k]); printf(" \n");}}/*选择排序*/void SelectSort(int r[],int n){int i,j,temp;for(i=0;i<n;i++){for(j=i+1;j<n;j++) /*不考虑后面元素,可视从j往前的数据都是排好的*/ {if(r[i]>r[j])/*如果当前元素r[j]比索引指向的元素r[i]小,换位*/ {temp=r[i];r[i]=r[j];r[j]=temp;}}}}/*返回要置换的位置*/int del(int a[],int num[],int n){int i,j;int s[4]={0,0,0,0};int t[4]={0,0,0,0};for(i=0;i<4;i++){for(j=n;j<20;j++){if(a[i]==num[j]){s[i]=j;t[i]=j;break;}}if(j==20){ s[i]=20;t[i]=20;}}SelectSort(s,4);for(i=0;i<4;i++){if(t[i]==s[3])break;}return i;}/*最佳置换算法*/void Optimal(int num[]){int i,j,k,temp;int a[4]={-1,-1,-1,-1} ;for(i=0,j=0;i<20;i++){if(j<4){if(have(a,num[i])==0) a[j++]=num[i];}else{if(have(a,num[i])==0) {temp=del(a,num,i); a[temp]=num[i];}}for(k=0;k<4;k++)printf(" %2d",a[k]); printf(" \n");}}void main(){loop: /* 循环 */{char ch;int i;int num[20];/*初始化页面调用数组*/for(i=0;i<20;i++){num[i]=rand()%10;printf(" %d",num[i]);}printf("\n");printf("----------------------------------\n");printf(" 1---FIFO;2---LRU;3---Optimal\n");printf("----------------------------------\n\n");printf("intput the NO. :");i=0;scanf("%d",&i);printf("\n [1] [2] [3] [4]\n");switch (i){case 1:FIFO(num);break;case 2:LRU(num); break;case 3:Optimal(num);break;default:printf("input wrong No.!!!");}printf("again?(y or n)\ninput:");loop_1:{ch=getch();if(ch=='y') /* y 再次输入 */goto loop;else if(ch=='n') /* n 退出 */exit(0);else /* 都不是提示输入错误 */{printf("\ninput wrong!again please!!!\ninput:"); goto loop_1;}}}}。
实验报告页面置换算法(c语言实现)
实验三页面置换算法#include<iostream.h>#include <stdlib.h>#include <time.h>#include <stdio.h>#define L 20int M; struct Proi nt num,time;};I nput(int m,Pro p[L]){i nt i,j,c;c out<<"请输入实际页面走向长度L(15<=L<=20):";d o{c in>>m;i f(m>20||m<15)cout<<"实际页面长度须在15~20之间;请重新输入L:";e lse break;}while(1);j=time(NULL);s rand(j);c out<<"输出随机数: ";f or(i=0;i<m;i++){p[i].num=rand( )%10+1;p[i].time=0;c out<<p[i].num<<" ";}c out<<endl;r eturn m;}v oid print(Pro *page1){P ro *page=new Pro[M];p age=page1;f or(int i=0;i<M;i++)i f(page[i].num==-1)c out<<" ";e lsec out<<page[i].num<<" ";c out<<"√"<<endl;}i nt Search(int e,Pro *page1 ){P ro *page=new Pro[M];p age=page1;f or(int i=0;i<M;i++) if(e==page[i].num) return i; r eturn -1;}i nt Max(Pro *page1){}i nt Count(Pro *page1,int i,int t,Pro p[L]){}i nt main(){i nt c;i nt m=0,t=0;f loat n=0;P ro p[L];c out<<"********************************************* "<<endl;c out<<" * 页式存储管理*"<<endl;c out<<"********************************************* "<<endl;c out<<"请输入可用内存页面数m(3~5): ";d o{c in>>M;i f(M>5||M<3)c out<<"内存块M须在3~5之间,请重新输入M:";e lse break;}while(1);m=Input(m,p);P ro *page=new Pro[M];c out<<"^-^欢迎进入操作系统界面^-^"<<endl;c out<<"1:FIFO页面置换"<<endl;c out<<"2:LRU页面置换"<<endl;c out<<"3:OPT页面置换"<<endl;c out<<"4:退出"<<endl;d o{c out<<"按1~4键操作:"<<endl;c in>>c;s ystem("cls");f or(int i=0;i<M;i++){p age[i].num=-1;p age[i].time=m-1-i;}i=0;i f(c==1){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" FIFO算法页面置换情况如下: "<<endl;cout<<endl;c out<<"******************************************"<<endl;w hile(i<m){i f(Search(p[i].num,page)>=0) {cout<<p[i].num<<" "; p[i].numc out<<"不缺页"<<endl;i++;}e lse {i f(t==M)t=0;e lse{n++;p age[t].num=p[i].num;c out<<p[i].num<<" ";p rint(page);t++;i++;}}}c out<<"缺页次数:"<<n<<" }i f(c==2){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" LRU算法页面置换情况如下: "<<endl;c out<<endl;c out<<"******************************************"<<endl;w hile(i<m){i nt a;t=Search(p[i].num,page);i f(t>=0){p age[t].time=0;for(a=0;a<M;a++)i f(a!=t)page[a].time++;cout<<p[i].num<<" ";c out<<"不缺页"<<endl;}e lse{n++; t=Max(page);page[t].num=p[i].num; page[t].time=0;cout<<p[i].num<<" ";p rint(page);f or(a=0;a<M;a++)i f(a!=t)page[a].time++;}i++;}c out<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl;}i f(c==3){n=0;c out<<"******************************************"<<endl;c out<<endl;c out<<" OPT算法置换情况如下:"<<endl;c out<<endl;c out<<"******************************************"<<endl;w hile(i<m){i f(Search(p[i].num,page)>=0){c out<<p[i].num<<" ";c out<<"不缺页"<<endl;i++;}e lse{i nt a=0;f or(t=0;t<M;t++)i f(page[t].num==0)a++;if(a!=0) {i nt q=M;f or(t=0;t<M;t++)i f(page[t].num==0&&q>t)q=t;p age[q].num=p[i].num;n++;c out<<p[i].num<<" ";p rint(page);i++;}e lse{i nt temp=0,s;f or(t=0;t<M;t++)i f(temp<Count(page,i,t,p)){t emp=Count(page,i,t,p);s=t;}page[s].num=p[i].num;n++;c out<<p[i].num<<" ";p rint(page);i++;}}}c out<<"缺页次数:"<<n<<" 缺页率:"<<n/m<<endl;}i f(c==4){c out<<" ^-^再见!^-^ "<<endl;}}while(c==1||c==2||c==3||c==4);r eturn 0;}结果:完成相关实验并且获得预期结果.。
页面置换算法c语言
页面置换算法(Page Replacement Algorithm)是操作系统中用于管理计算机内存的一种算法。
当系统中的物理内存不足时,操作系统会选择内存中的一些页面,将它们从内存中移动到磁盘上,以便为新的页面提供空间。
以下是使用C语言实现FIFO(First-In, First-Out)页面置换算法的示例代码:c复制代码#include<stdio.h>#include<stdlib.h>#define MAX_FRAMES 100#define MAX_PAGES 1000int frames[MAX_FRAMES];int page_faults = 0;void insert(int page, int frames[], int* page_faults) {int i;for (i = 0; i < *page_faults; i++) {if (frames[i] == page) {// Page already exists in memoryreturn;}}for (i = *page_faults; i < MAX_FRAMES; i++) {if (frames[i] == -1) {// Frame is empty, insert page at the end of the arrayframes[i] = page;(*page_faults)++;return;}}// All frames are full, page must be replaced to make room for the new page frames[*page_faults] = page;(*page_faults)++;}int main() {int pages[MAX_PAGES];int num_pages, num_frames, i, j;int page_faults_array[MAX_PAGES];int page_faults = 0;int current_frames[MAX_FRAMES];for (i = 0; i < MAX_FRAMES; i++) {current_frames[i] = -1; // Initialize all frames as empty}printf("Enter the number of pages: ");scanf("%d", &num_pages);printf("Enter the number of frames: ");scanf("%d", &num_frames);for (i = 0; i < num_pages; i++) {printf("Enter page %d: ", i + 1);scanf("%d", &pages[i]);insert(pages[i], current_frames, &page_faults); // Insert page into memorypage_faults_array[i] = page_faults; // Store page fault count for each page in an array}printf("Page Faults: %d\n", page_faults); // Print total number of page faults for the entire sequence of pagesprintf("Page Faults for each page in the sequence:\n"); // Print page fault count for each page in the sequence of pagesfor (i = 0; i < num_pages; i++) {printf("Page %d: %d\n", pages[i], page_faults_array[i]); // Print the page fault count for each page in the array of page fault counts for each page in the sequence of pages (nested array) (Duh) (Sorry for the confusion) (It's actually not that confusing once you see it written out like this) (If you're still con。
先进先出(FIFO)页面置换算法C语言实现、最近最久未使用(LRU)页面置换算法C语言实现
先进先出(FIFO)页⾯置换算法C语⾔实现、最近最久未使⽤(LRU)页⾯置换算法C语⾔实现1.实现效果2.实现源代码1 #include<iostream>2 #include<process.h>3 #include<stdlib.h>4 #include<ctime>5 #include<conio.h>6 #include<stdio.h>7 #include<string.h>8using namespace std;910#define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|\n")/*表格控制*/11#define bsize 4 //物理块⼤⼩12#define psize 16 //进程⼤⼩13void chushihua();//初始化函数14void ymzh();16void changeaddr(struct Page p[], int logaddr);17void dizhizhuanhuan();18void menu();19int wang();2021int yemianliu[32]={0};//全局变量数组,地址流22int p;23struct Page {24int pno;//页号25int flag;//标志位26int cno;//主存号27int modf;//修改位28int addr;//外存地址29 }Page; //全局变量p是⼀共有多少地址流3031 typedef struct pagel32 {33int num; /*记录页⾯号*/34int time; /*记录调⼊内存时间*/35 }Pagel; /*页⾯逻辑结构,⽅便算法实现*/3637 Pagel b[bsize]; /*内存单元数*/38int c[bsize][psize];/*保存内存当前的状态:缓冲区*/39int queue[100];/*记录调⼊队列*/40int k;/*调⼊队列计数变量*/41int phb[bsize]={0};//物理块标号42int pro[psize]={0};//进程序列号43int flag[bsize]={0};//进程等待次数(存放最久未被使⽤的进程标志)*/ 44int i=0,j=0;//i表⽰进程序列号,j表⽰物理块号*/45int m =-1,n =-1;//物理块空闲和进程是否相同判断标志*/46int mmax=-1, maxflag=0;//标记替换物理块进程下标*/47int count =0; //统计页⾯缺页次数4849void chushihua() //初始化函数50 {51int t;52 srand(time(0));//随机产⽣指令序列53 p=12+rand()%32;54 cout<<"地址流序列:";55 cout<<endl;56for(i=0; i<p; i++)57 {58 t=1+rand()%9;59 yemianliu[i]=t;//将随机产⽣的指令数存⼊页⾯流60 }61for (i=p-1;i>=0;i--)62 {63 cout<<yemianliu[i]<<"";64 }65 cout<<endl;66 }67void ymzh()68 {69 chushihua();70 yemianzhihuan();71 }7273void yemianzhihuan()74 {75int a;76 printf("----------------------------------\n");77 printf("☆☆欢迎使⽤分页模拟实验系统☆☆\n");78 printf("----------------------------------");79 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");80 printf("☆☆1.进⼊硬件地址变换算法☆☆\n");81 printf("☆☆------------------------☆☆\n");82 printf("☆☆2.进⼊页⾯置换算法☆☆\n");83 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");84 printf("请输⼊您的选择:");85switch(a)86 {87case1:88 ymzh();89break;90case2:91 wang();92break;93default:94 cout<<"输⼊有误,请重新输⼊!"<<endl;95break;96 }97 }98100int j=logaddr/64;//对应的块号101int k=logaddr%64; //对应的偏移量102int flag=0;103int addr;104for(int i=0;i<8;i++)105 {106if(p[i].pno==j)//找到对应的页号107 {108if(p[i].flag==1)//页⾯标志为1109 {110 addr=p[i].cno*64+k;111 cout<<"物理地址为:"<<addr<<endl;112 cout<<"详细信息:"<<"\t页⾯号:"<<p[i].pno<<"\t 主存号:"<<p[i].cno<<"\t偏移量:"<<k<<endl; 113 flag=1;114break;115 }116 }117 }118119if(flag==0)120 cout<<"该页不在主存,产⽣缺页中断"<<endl;121 }122123void dizhizhuanhuan()124 {125int a;126int ins;//指令逻辑地址127struct Page p[8];128 p[0].pno=0;p[0].flag=1;p[0].cno=5;p[0].modf=1;p[0].addr=011;129 p[1].pno=1;p[1].flag=1;p[1].cno=8;p[1].modf=1;p[1].addr=012;130 p[2].pno=2;p[2].flag=1;p[2].cno=9;p[2].modf=0;p[2].addr=013;131 p[3].pno=3;p[3].flag=1;p[3].cno=10;p[3].modf=0;p[3].addr=015;132 p[4].pno=4;p[4].flag=0;p[4].addr=017;133 p[5].pno=5;p[5].flag=0;p[5].addr=025;134 p[6].pno=6;p[6].flag=0;p[6].addr=212;135 p[7].pno=7;p[7].flag=0;p[7].addr=213;136 printf("\t\t\t--------------------------------\n");137 printf("\t\t\t☆☆欢迎使⽤分页模拟实验系统☆☆\n");138 printf("\t\t\t---------------------------------\n");139 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");140 printf("\t\t\t☆☆1.输⼊指令☆☆\n");141 printf("\t\t\t☆☆------------------------☆☆\n");142 printf("\t\t\t☆☆2.进⼊页⾯置换算法☆☆\n");143 printf("\t\t\t☆☆------------------------☆☆\n");144 printf("\t\t\t☆☆0.EXIT ☆☆\n");145 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");146while(a!=0)147 {148 cout<<endl<<"请输⼊您的选择:";149 cin>>a;150151 cout<<"页号"<<"标记位"<<"外存地址"<<"主存号"<<endl;152for(int i=0;i<8;i++)153 {154 cout<<p[i].pno<<"\t"<<p[i].flag<<"\t"<<p[i].addr<<"\t";155if(p[i].flag)156 cout<<p[i].cno;157 cout<<endl;158 }159160switch(a)161 {162case0:printf("\t\t\t再见!\t\t\t\n"); break;163case1:164 cout<<"请输⼊指令的逻辑地址:";165 cin>>ins;166 changeaddr(p, ins);break;167case2: system("CLS"); a=wang();break;168default:cout<<"输⼊有误,请重新输⼊!"<<endl;break;169 }170 }171 }172173void menu()174 {175int a;176 printf("\t\t\t--------------------------------\n");177 printf("\t\t\t☆☆欢迎使⽤分页模拟实验系统☆☆\n");178 printf("\t\t\t---------------------------------\n");179 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");180 printf("\t\t\t☆☆1.输⼊指令☆☆\n");181 printf("\t\t\t☆☆------------------------☆☆\n");182 printf("\t\t\t☆☆2.进⼊页⾯置换算法☆☆\n");184 printf("\t\t\t☆☆0.EXIT ☆☆\n");185 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n"); 186 printf("请选择所要执⾏的操作:");187 scanf("%d",&a);188switch(a)189 {190case0: printf("\t\t\t-再见!-\t\t\t\n");break;191case1: dizhizhuanhuan (); break;192case2: wang (); break;193default:cout<<"输⼊有误,请重新输⼊!"<<endl;break; 194 }195 }196int main()197 {198 menu();199 }200201//****************随机产⽣序列号函数202int* build()203 {204 printf("随机产⽣⼀个进程序列号为:\n");205int i=0;206for(i=0; i<psize; i++)207 {208 pro[i]=10*rand()/(RAND_MAX+1)+1;209 printf("%d ", pro[i]);210 }211 printf("\n");212return(pro);213 }214215//***************************************查找空闲物理块216int searchpb()217 {218for (j=0;j<bsize; j++)219 {220if(phb[j] == 0)221 {222 m=j;223return m;224break;225 }226 }227return -1;228 }229//************************************查找相同进程230int searchpro()231 {232for(j=0;j< bsize;j++)233 {234if(phb[j] =pro[i])235 {236 n=j;237return j;238 }239 }240return -1;241 }242243//*************************初始化内存244void empty()245 {246for(i=0;i<bsize;i++)247 phb[i]=0;248 count=0; //计数器置零249 } //******先进先出页⾯置换算法250void FIFO()251 {252for( i=0; i<psize; i++)253 {254// m=searchpb();255// n=searchpro();256//找到第⼀个空闲的物理快257for(j=0;j<bsize;j++) {258if(phb[j] == 0){259 m=j;260break;261 }262 }263//找与进程相同的标号264for(j=0;j<bsize;j++) {265if(phb[j] == pro[i]){266 n=j;268 }269270//找flag值最⼤的271for(j=0;j<bsize;j++)272 {273if(flag[j]>maxflag)274 {275 maxflag = flag[j];276 mmax = j;277 }278 }279280if(n == -1)//不存在相同进程281 {282if(m != -1)//存在空闲物理块283 {284 phb[m]=pro[i];//进程号填⼊该空闲物理块285// count++;286 flag[m]=0;287for (j=0;j<=m; j++)288 {289 flag[j]++;290 }291 m=-1;292 }293else//不存在空闲物理块294 {295 phb[mmax] =pro[i];296 flag[mmax] =0;297for (j=0;j<bsize;j++)298 {299 flag[j]++;300 }301 mmax = -1;302 maxflag = 0;303 count++;304 }305 }306else//存在相同的进程307 {308 phb[n] = pro[i];309for(j=0;j<bsize;j++)310 {311 flag[j]++;312 }313 n=-1;314 }315for(j=0;j < bsize;j++)316 {317 printf("%d ", phb[j]);318 }319 printf("\n");320 }321 printf("缺页次数为:%d\n",count);322 printf("缺页率 :%16. 6f",(float)count/psize);323 printf("\n");324 }325/*初始化内存单元、缓冲区*/326void Init(Pagel *b,int c[bsize][psize])327 {328int i,j;329for (i=0;i<psize;i++)330 {331 b[i].num=-1;332 b[i].time=psize-i-1;333 }334for(i=0;i<bsize;i++)335for(j=0;j<psize;j++)336 c[i][j]=-1;337 }338/*取得在内存中停留最久的页⾯,默认状态下为最早调⼊的页⾯*/ 339int GetMax(Pagel *b)340 {341int i;342int max=-1;343int tag=0;344for(i=0;i<bsize;i++)345 {346if(b[i].time>max)347 {348 max=b[i].time;349 tag= i;350 }353 }354355/*判断页⾯是否已在内存中*/356int Equation(int fold, Pagel *b)357 {358int i;359for(i=0;i<bsize;i++)360 {361if(fold==b[i]. num)362return i;363 }364return -1;365 }366/*LRU核⼼部分*/367void Lruu(int fold, Pagel *b)368 {369int i;370int val;371 val=Equation(fold, b);372if (val>=0)373 {374 b[val].time=0;375for(i=0;i<bsize;i++)376if (i!=val)377 b[i].time++;378 }379else380 {381 queue[++k]=fold;/*记录调⼊页⾯*/382 val=GetMax(b);383 b[val].num=fold;384 b[val].time=0;385for (i=0;i<bsize;i++){386387// URLcount++;388if (i!=val)389 b[i].time++;390 }391 }392 }393394void LRU()395 {396int i,j;397 k=0;398 Init(b, c);399for(i=0; i<psize; i++)400 {401 Lruu(pro[i],b);402 c[0][i]=pro[i];403/*记录当前的内存单元中的页⾯*/404for(j=0;j<bsize;j++)405 c[j][i]=b[j].num;406 }407408/*结果输出*/409 printf("内存状态为:\n");410 Myprintf;411for(j=0;j<psize;j++)412 printf("|%2d", pro[j]);413 printf("|\n");414 Myprintf;415416for(i=0;i<bsize;i++)417 {418for(j=0; j<psize; j++)419 {420if(c[i][j]==-1)421 printf("|%2c",32);422else423 printf("|%2d",c[i][j]);424 }425 printf("|\n");426 }427428 Myprintf;429// printf("\n调⼊队列为:");430// for(i=0;i<k;i++)431// printf("%3d", queue[i]);432433 printf("\n缺页次数为:%6d\n 缺页率 :%16. 6f", k+1,(float)(k+1)/psize); 434 }437int wang()438 {439int sel;440do{441 printf("\t\t\t--------------------------------\n");442 printf("\t\t\t☆☆欢迎使⽤分页模拟实验系统☆☆\n");443 printf("\t\t\t---------------------------------\n");444 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");445 printf("\t\t\t☆☆虚拟内存☆☆\n");446 printf("\t\t\t☆☆------------------------☆☆\n");447 printf("\t\t\t☆☆1.产⽣随机序列☆☆\n");448 printf("\t\t\t☆☆------------------------☆☆\n");449 printf("\t\t\t☆☆2.最近最久未使⽤☆☆\n");450 printf("\t\t\t☆☆------------------------☆☆\n");451 printf("\t\t\t☆☆3.先进先出☆☆\n");452 printf("\t\t\t☆☆------------------------☆☆\n");453 printf("\t\t\t☆☆0.退出☆☆\n");454 printf("\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");455 printf("请选择所要执⾏的操作:");456 scanf("%d",&sel);457switch(sel)458 {459case0: printf("\t\t\t再见!t\t\t\n"); break;460case1: build(); break;461case2: printf("最近最久未使⽤\n"); LRU();empty(); printf("\n");break; 462case3: printf("先进先出算法\n"); FIFO();empty();printf("\n");break; 463default:printf("请输⼊正确的选项号!");printf("\n\n");break;464 }465 }while(sel !=0 );466return sel;467 }。
lru页面置换算法实验c语言总结
LRU页面置换算法实验C语言总结1.引言在计算机科学中,页面置换算法是解决主存容量有限的情况下,如何有效地管理页面(或称为内存块)的一种重要方法。
L RU(L ea st Re ce nt ly Us e d)页面置换算法是其中一种经典的策略,通过淘汰最久未使用的页面来提高内存的利用率。
本文将总结使用C语言实现L RU页面置换算法的相关实验。
2.算法原理L R U页面置换算法的核心思想是:最近被访问的页面可能在未来继续被访问,而最久未被使用的页面可能在未来也不再被访问。
基于这一思想,L R U算法维护一个页面访问的时间顺序链表,每次发生页面置换时,选择链表头部(即最久未使用)的页面进行淘汰。
3.实验设计本次实验旨在使用C语言实现LR U页面置换算法,并通过模拟页面访问的过程来验证算法的正确性。
具体设计如下:3.1数据结构为了实现LR U算法,我们需要定义几个关键的数据结构:3.1.1页面节点结构t y pe de fs tr uc tP age{i n tp ag eI D;//页面I Ds t ru ct Pa ge*n ex t;//下一个节点指针s t ru ct Pa ge*p re v;//上一个节点指针}P ag e;3.1.2内存块结构t y pe de fs tr uc tM emo r y{i n tc ap ac it y;//内存块容量i n ts iz e;//当前存储的页面数量P a ge*h ea d;//内存块链表头指针P a ge*t ai l;//内存块链表尾指针}M em or y;3.2实验步骤本次实验主要包括以下几个步骤:3.2.1初始化内存块根据实际需求,设置内存块的容量,并初始化链表头指针和尾指针。
3.2.2页面置换每次发生页面访问时,检查访问的页面是否已经在内存块中。
如果在,将该页面移动到链表尾部;如果不在,执行页面置换。
3.2.3页面淘汰当内存块已满时,选择链表头部的页面进行淘汰,将新访问的页面加入链表尾部。
操作系统页面置换算法代码
操作系统页面置换算法代码2007年01月20日星期六下午12:53#include <stdio.h>#include <stdlib.h>#include <unistd.h>#define TRUE 1#define FALSE 0#define INV ALID -1#define NUL 0#define total_instruction 320 /*指令流长*/#define total_vp 32 /*虚页长*/#define clear_period 50 /*清零周期*/typedef struct{ /*页面结构*/int pn,pfn,counter,time;}pl_type;pl_type pl[total_vp]; /*页面结构数组*/struct pfc_struct{ /*页面控制结构*/int pn,pfn;struct pfc_struct *next;};typedef struct pfc_struct pfc_type;pfc_type pfc[total_vp],*freepf_head,*busypf_head,*busypf_tail;int diseffect,a[total_instruction];int page[total_instruction], offset[total_instruction];void initialize();void FIFO();void LRU();void NUR();int main(){int S,i;srand((int)getpid());S=(int)rand()%390;for(i=0;i<total_instruction;i+=1) /*产生指令队列*/ {a[i]=S; /*任选一指令访问点*/ a[i+1]=a[i]+1; /*顺序执行一条指令*/ a[i+2]=(int)rand()%390; /*执行前地址指令m’*/a[i+3]=a[i+2]+1; /*执行后地址指令*/ S=(int)rand()%390;}for(i=0;i<total_instruction;i++) /*将指令序列变换成页地址流*/ {page[i]=a[i]/10;offset[i]=a[i]%10;}for(i=4;i<=32;i++) /*用户内存工作区从4个页面到32个页面*/{printf("%2d page frames",i);FIFO(i);LRU(i);NUR(i);printf("\n");}return 0;}void FIFO(total_pf) /*FIFO(First in First out)ALGORITHM*/int total_pf; /*用户进程的内存页面数*/{int i;pfc_type *p, *t;initialize(total_pf); /*初始化相关页面控制用数据结构*/ busypf_head=busypf_tail=NUL; /*忙页面队列头,对列尾链接*/for(i=0;i<total_instruction;i++){if(pl[page[i]].pfn==INV ALID) /*页面失效*/{diseffect+=1; /*失效次数*/if(freepf_head==NUL) /*无空闲页面*/{p=busypf_head->next;pl[busypf_head->pn].pfn=INV ALID; /*释放忙页面队列中的第一个页面*/freepf_head=busypf_head;freepf_head->next=NUL;busypf_head=p;}p=freepf_head->next; /*按方式调新页面入内存页面*/freepf_head->next=NUL;freepf_head->pn=page[i];pl[page[i]].pfn=freepf_head->pfn;if(busypf_tail==NUL)busypf_head=busypf_tail=freepf_head;else{busypf_tail->next=freepf_head;busypf_tail=freepf_head;}freepf_head=p;}}printf("FIFO:%6.4F",1-(float)diseffect/320);}void LRU(total_pf)int total_pf;{int min,minj,i,j,present_time;initialize(total_pf);present_time=0;for(i=0;i<total_instruction;i++){if(pl[page[i]].pfn==INV ALID) /*页面失效*/ {diseffect++;if(freepf_head==NUL) /*无空闲页面*/{min=32767;for(j=0;j<total_vp;j++)if(min>pl[j].time&&pl[j].pfn!=INV ALID){min=pl[j].time;minj=j;}freepf_head=&pfc[pl[minj].pfn];pl[minj].pfn=INV ALID;pl[minj].time=-1;freepf_head->next=NUL;}pl[page[i]].pfn=freepf_head->pfn;pl[page[i]].time=present_time;freepf_head=freepf_head->next;}elsepl[page[i]].time=present_time;present_time++;}printf("LRU:%6.4f",1-(float)diseffect/320);}void NUR(total_pf)int total_pf;{int i,j,dp,cont_flag,old_dp;pfc_type *t;initialize(total_pf);dp=0;for(i=0;i<total_instruction;i++){if(pl[page[i]].pfn==INV ALID) /*页面失效*/{diseffect++;if(freepf_head==NUL) /*无空闲页面*/{cont_flag=TRUE;old_dp=dp;while(cont_flag)if(pl[dp].counter==0&&pl[dp].pfn!=INV ALID)cont_flag=FALSE;else{dp++;if(dp==total_vp)dp=0;if(dp==old_dp)for(j=0;j<total_vp;j++)pl[j].counter=0;}freepf_head=&pfc[pl[dp].pfn];pl[dp].pfn=INV ALID;freepf_head->next=NUL;}pl[page[i]].pfn=freepf_head->pfn;freepf_head=freepf_head->next;}elsepl[page[i]].counter=1;if(i%clear_period==0)for(j=0;j<total_vp;j++)pl[j].counter=0;}printf("NUR:%6.4f",1-(float)diseffect/320);}void initialize(total_pf) /*初始化相关数据结构*/int total_pf; /*用户进程的内存页面数*/{int i;diseffect=0;for(i=0;i<total_vp;i++){pl[i].pn=i;pl[i].pfn=INV ALID; /*置页面控制结构中的页号,页面为空*/pl[i].counter=0;pl[i].time=-1; /*页面控制结构中的访问次数为0,时间为-1*/}for(i=1;i<total_pf;i++){pfc[i-1].next=&pfc[i];pfc[i-1].pfn=i-1;/*建立pfc[i-1]和pfc[i]之间的连接*/}pfc[total_pf-1].next=NUL;pfc[total_pf-1].pfn=total_pf-1;freepf_head=&pfc[0]; /*页面队列的头指针为pfc[0]*/}模拟LRU页面置换算法2010/02/01 16:33#include<stdio.h>#include<stdlib.h>#define PAGENUM 6 /*主存中允许的最大的页数*/#define MAXPAGENUM 15 /* 一个程序包含的最大页数*//*定义栈的结构即置换器*/typedef struct stack{int page[PAGENUM];int head;}PAGER;/*定义一个置换器*/PAGER pager;/*栈的初始化*/void InitPager(){int top = 0;int i,j,tmp;int r;randomize();r = random(MAXPAGENUM);pager.page[top++] = r;while(top < PAGENUM ){randomize();r = random(MAXPAGENUM);for(j =0;j<top;j++){if(r == pager.page[j]){break;}if(j == top-1)pager.page[top++] = r;}}pager.head = PAGENUM - 1;}/*栈中成员的移动,即移动页面的操作*/ void MovingPage(int Begin ){int i;for(i = Begin; i < PAGENUM-1; i++){pager.page[i] = pager.page[i+1] ;}}/*出栈操作,即交换出页面的操作*/ void PopPage(int p){MovingPage(p);pager.head = PAGENUM - 2;}/*入栈操作,即换进新页面的操作*/ void PushPage(int page){pager.head = PAGENUM-1;pager.page[pager.head] = page;}/*打印主存中的页面*/void printPager(){int i;printf("The pages in the pager is:");for(i = 0; i< PAGENUM;i++){printf(" %d ",pager.page[i]);}printf("\n");}/*处理页面的换进和换出*/void PagingProcess(){int rdm;int i;randomize();rdm = random(MAXPAGENUM);for(i = 0; i< PAGENUM; i++){if(rdm == pager.page[i]){printPager();printf("The page [%d] will be accessed\n",rdm);PopPage(i);PushPage(rdm);printPager();break;}if(i == PAGENUM-1){printPager();printf("The page [0] will be paged out\n");PopPage(0);printf("The page [%d] will be paged in\n",rdm);PushPage(rdm);printPager();}}}int main(){int i;clrscr();for(i = 0; i<3; i++){InitPager();printf("ROUND %d:\n\n",i+1);PagingProcess();}getch();return 0;页面调度算法(FIFO,LRU,OPT) 2006-11-22 19:29#include< iostream.h > #include"stdlib.h" typedef int QElemType; #define ok 1#define overflow 0#define error 0typedef struct Qnode { QElemType data;struct Qnode *next;}Qnode,*Queueptr; typedef struct { Queueptr front; Queueptr rear;}LinkQueue;InitQueue( LinkQueue &Q ) {Q.front = Q.rear = ( Queueptr )malloc( sizeof( Qnode )); if( !Q.front ) exit ( overflow );Q.front->next =NULL;return ok;}EnQueue( LinkQueue &Q,QElemType e ) {Queueptr p;p = ( Queueptr )malloc( sizeof( Qnode ));if( !p ) exit( overflow );p->data = e;p->next = NULL;Q.rear->next = p;Q.rear = p;return ok;}DeQueue( LinkQueue &Q,QElemType &e ) {Queueptr p;if( Q.front == Q.rear ) return error;p = Q.front->next;e = p->data;Q.front->next = p->next;if( Q.rear == p ) Q.rear = Q.front;free( p );return ok;}void VisitQueue( LinkQueue Q ) {Queueptr p;p = Q.front->next;while( p ) { cout << p->data << " ";p = p->next; } }CompareQueue( LinkQueue Q,int page ) {Queueptr p;p = Q.front->next;while( p ) {if( p->data == page ) return ok;p = p->next;}return error;}void FIFO( int *a,int n,int m ) {LinkQueue Q;int page, t = 0,flag = 0,x;InitQueue( Q );for( int i = 1;i <= m;i++ ){page = a[ i ];t++;if( t <= n ) { EnQueue( Q,page );cout << a[ i ] << " "; }else {for( int j = 1;j <= n;j++ )if( CompareQueue( Q,page ) ) { t--;flag = 1;break; }if( flag == 0 ) { DeQueue( Q,x );cout << x << " was taken out " << page << " was taken in";EnQueue( Q,page );}cout << endl;VisitQueue( Q );cout << ":";}flag = 0;}cout << "缺页中断数为:" << endl;cout << "t= " << t << endl;}void LRU( int *a,int n,int m ) {LinkQueue Q;int page, t = 0,flag = 0,x,e;InitQueue( Q );for( int i = 1;i <= m;i++ ){page = a[ i ];t++;if( t <= n ) { EnQueue( Q,page );cout << a[ i ] << " "; }else { for( int j = 1;j <= n;j++ )if( CompareQueue( Q,page ) ) { t--;DeQueue(Q,e);EnQueue(Q,e);flag = 1;break; }if( flag == 0 ) { DeQueue( Q,x );cout << x << " was taken out " << page << " was taken in";EnQueue( Q,page );}cout << endl;VisitQueue( Q );cout << ":";}flag = 0;}cout << "缺页中断数为:" << endl;cout << "t= " << t << endl;}int max( int *t,int n ){int max =t[ 1 ],s = 1;for( int i = 1;i <= n;i++ )if( t[ i ] > max ) {max = t[ i ];s = i;} return s;}void OPT( int a[ 21 ],int n,int m ) {int w = 0,flag = 0;int *t =new int[ n + 1 ];for( int i = 1;i <= m;i++ )w++;if( w <= n ) cout << a[ i ] << " " ;else{for( int q = 1;q <= n;q++ )if( a[ i ] == a[ q ] ) { w--;flag = 1;break; } if( flag == 0 ){for( int j = 1;j <= n;j++ )for( int k = i;k <= m;k++ ){if( a[ j ] != a[ k ] ) t[ j ]++;else break;}cout << a[ max( t,n ) ] << " " << "was taken out" << " " << a[ i ] << " was taken in ";a[ max( t,n ) ] = a[ i ];}cout << endl;for( int s = 1;s <= n;s++ )cout << a[ s ] << " ";cout << ":";}for( int r = 1;r <= n;r++ ) t[ r ] = 0; flag = 0;}cout << "缺页中断数为:" << endl;cout << "w = " << w << endl;delete [] a;}main(){int m,n;cout << "输入页面数:" << endl;cin >> m;int *a = new int[ m + 1 ];cout << "输入驻留集大小:" << endl;cin >> n;cout << "input the pages" << endl;for( int i = 1;i <= m;i++ )cin >> a[ i ];cout << endl;cout << "The result of FIFO:" << endl; FIFO( a,n,m );cout << endl;cout << "The result of LRU:" << endl; LRU( a,n,m );cout << endl;cout << "The result of OPT:" << endl; OPT( a,n,m );cout << endl;return 0;delete [] a;}模拟FIFO页面调度算法处理缺页中断2009-11-28 16:14模拟FIFO页面调度算法处理缺页中断#include<iostream.h>#include<math.h>class List;class item{public:friend class List;private:item(int p=0,int s=0,int b=0,int l=0,int c=0){page=p;sign=s;block=b;locate=l;changesign=c;next=NULL;}item *next;int page;int sign;int changesign;int block;int locate;};class List{public:List(int p=0,int s=0,int b=0,int l=0,int c=0){list=new item(p,s,b,l,c);}int check(int p);int insert(int p,int s,int b,int l);void print();int append(int p,int s,int b,int l);int length();int alternative(int k,int p);void reverse();private:item *list;item *end();};int List ::alternative(int k,int p){int n,m;item *pt=list,*pr=list;for(int temp=1;temp<=k;temp++){pt=pt->next;}cout<<endl;n=pt->block;cout<<"被调换的页的页号为:"<<pt->page<<" 该页所对应的修改标志位为:"<<pt->changesign<<endl;cout<<"被调入的页的页号为:"<<p<<endl;cout<<"*****************************************"<<endl;cout<<"请输入被调入页的磁盘地址:";cin>>m;for(;pr;pr=pr->next){if(pr->locate==m){cout<<"该磁盘地址已存有数据,请选择另外的磁盘地址进行存储:";cin>>m;pr=list;}}//cout<<"++++++++++++++++++++++++++++++++++"<<endl;pt->locate=m;pt->page=p;return n;}void List :: print(){if(list==0)cout<<"页表中无数据!"<<endl;cout<<"页号标志主存块号修改标志磁盘地址"<<endl;item *pt=list;while(pt){cout<<" "<<pt->page<<" "<<pt->sign<<" "<<pt->block<<" "<<pt->changesign<<" "<<pt->locate<<endl;pt=pt->next;}cout<<endl;}int List::append(int p,int s,int b,int l){item *pt=new item(p,s,b,l);if(list==0)list=pt;else{(end())->next=pt;}return 1;}item *List::end(){item *prv,*pt;for(prv=pt=list;pt;prv=pt,pt=pt->next) ;return prv;}int List::insert(int p,int s,int b,int l) {item *pt=new item(p,s,b,l);pt->next=list;list=pt;return 1;}int List::length(){int cnt=0;item *pt=list;for(;pt;pt=pt->next,cnt++);return cnt;}int List::check(int p){item *pt=list;int a=-1;for(;pt;pt=pt->next){if(pt->page==p&&pt->sign==1)a=pt->block;}return a;}void List::reverse(){item *pt,*prv,*tmp;prv=NULL;pt=list;list=end();while(pt!=list){tmp=pt->next;pt->next=prv;prv=pt;pt=tmp;}list->next=prv;}int checkp(int n);int main(){int j=0;List list(0,1,5,11);list.append(1,1,8,12);list.append(2,1,9,13);list.append(3,1,1,21);//list.append(4,0,-1,22);//list.append(5,0,-1,23);//list.append(6,0,-1,121);j=list.length();cout<<"************************模拟FIFO页面调度算法处理缺页中断************************"<<endl;cout<<"页表初始长度为:"<<j<<endl;cout<<"++++++++++++++++++++++++++++页表初始状态如下+++++++++++++++++++++++++++++++"<<endl;list.print();char a[12]={'+','+','*','I','O','-','M','+','I','O','+','I'};int b[12]={70,50,15,21,56,40,53,23,37,78,1,84};int m=0,n;int k=0;int c=0;for(int i=0;i<12;i++){int t;cout<<"*************************"<<"第"<<i+1<<"步["<<a[i]<<"]操作!"<<"*************************"<<endl;cout<<"请输入该操作对应的页号:";cin>>n;cout<<"*************************************************"<<endl;m=list.check(n);t=checkp(n);if(t==1){if(m==-1){cout<<"*缺页中断,页号:"<<n<<endl;cout<<"****************调用FIFO页面调度算法处理中断**************";c=list.alternative(k,n);k=(k+1)%j;cout<<"该页所在的主存块号为:"<<c<<endl;cout<<"该指令的物理地址为:"<<n<<b[i]<<endl;cout<<"********************"<<"中断处理后页表的状态"<<"*******************"<<endl;}else{cout<<"该指令的物理地址为:"<<n<<b[i]<<endl;}}if(m!=-1&&t==0){cout<<"该页所在主存块号:"<<m<<endl;m*=128+b[i];//cout<<"+++++++++++++++++++++++++++++++"<<endl;cout<<"该指令的物理地址为:"<<m<<endl;//cout<<"+++++++++++++++++++++++++++++++"<<endl;}else if(m==-1&&t==0){cout<<"*缺页中断,页号:"<<n<<endl;//cout<<"++++++++++++++++++++++++++++++++++";cout<<"****************调用FIFO页面调度算法处理中断**************";c=list.alternative(k,n);k=(k+1)%j;cout<<"该页所在的主存块号为:"<<c<<endl;//cout<<"++++++++++++++++++++++++++++++++++"<<endl;cout<<"该指令的物理地址为:"<<c*128+b[i]<<endl;//cout<<"++++++++++++++++++++++++++++++++++"<<endl;cout<<"********************"<<"中断处理后页表的状态"<<"*******************"<<endl;}else;list.print();//cout<<"-------------------------------------------------------------------"<<endl;}return 1;}int checkp(int n){int a=0;int k=1;for(int c=(int)sqrt(double (n))+2;c>=1;c--) {if(n==k)a=1;elsek=k*2;}return a;}。
实验四 页面置换算法代码(一)
实验四页面置换算法模拟(2)一.题目要求:设计一个虚拟存储区和存工作区,编程序演示下述算法的具体实现过程,并计算访问命中率:要求设计主界面以灵活选择某算法,且以下算法都要实现1) 最佳置换算法(OPT):将以后永不使用的或许是在最长(未来)时间不再被访问的页面换出。
2) 先进先出算法(FIFO):淘汰最先进入存的页面,即选择在存中驻留时间最久的页面予以淘汰。
3) 最近最久未使用算法(LRU):淘汰最近最久未被使用的页面。
4) 最不经常使用算法(LFU)二.实验目的:1、用C语言编写OPT、FIFO、LRU,LFU四种置换算法。
2、熟悉存分页管理策略。
3、了解页面置换的算法。
4、掌握一般常用的调度算法。
5、根据方案使算法得以模拟实现。
6、锻炼知识的运用能力和实践能力。
三.相关知识:1.虚拟存储器的引入:局部性原理:程序在执行时在一较短时间仅限于某个部分;相应的,它所访问的存储空间也局限于某个区域,它主要表现在以下两个方面:时间局限性和空间局限性。
2.虚拟存储器的定义:虚拟存储器是只具有请求调入功能和置换功能,能从逻辑上对存容量进行扩充的一种存储器系统。
3.虚拟存储器的实现方式:分页请求系统,它是在分页系统的基础上,增加了请求调页功能、页面置换功能所形成的页面形式虚拟存储系统。
请求分段系统,它是在分段系统的基础上,增加了请求调段及分段置换功能后,所形成的段式虚拟存储系统。
4.页面分配:平均分配算法,是将系统中所有可供分配的物理块,平均分配给各个进程。
按比例分配算法,根据进程的大小按比例分配物理块。
考虑优先的分配算法,把存中可供分配的所有物理块分成两部分:一部分按比例地分配给各进程;另一部分则根据个进程的优先权,适当的增加其相应份额后,分配给各进程。
5.页面置换算法:常用的页面置换算法有OPT、FIFO、LRU、Clock、LFU、PBA等。
四.设计思想:选择置换算法,先输入所有页面号,为系统分配物理块,依次进行置换:OPT基本思想:是用一维数组page[pSIZE]存储页面号序列,memery[mSIZE]是存储装入物理块中的页面。
页面置换算法实例page
//页面置换算法实例page.c//运行环境Redhad9.0 gcc 4.0#include "stdio.h"#include "stdlib.h"#define Bsize 3#define Psize 20struct pageInfor {int content; /*页面号*/int timer; /*被访问标记*/};PRA(void); /*初始化*/int findSpace(void); /*查找是否有空闲内存*/int findExist(int curpage);/*查找内存中是否有该页面*/int findReplace(void); /*查找应予置换的页面*/void display(void); /*显示*/void FIFO(void); /*FIFO算法*/void LRU(void); /*LRU算法*/void Optimal(void); /*OPTIMAL算法*/void BlockClear(void); /*BLOCK恢复*/struct pageInfor * block; /*物理块*/struct pageInfor * page; /*页面号串*/PRA(void){int QString[20]={7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1},i;block = (struct pageInfor *)malloc(sizeof(struct pageInfor));for(i=0; i<Bsize; i++) {block[i].content = -1;block[i].timer = 0;}page = (struct pageInfor *)malloc(sizeof(struct pageInfor)*Psize);for(i=0; i<Psize; i++) {page[i].content = QString[i];page[i].timer = 0;}}int findSpace(void){int i=0;for(i=0; i<Bsize; i++)if(block[i].content == -1)return i; /*找到空闲内存,返回BLOCK中位置*/ return -1;}int findExist(int curpage){int i=0;for(i=0; i<Bsize; i++)if(block[i].content == page[curpage].content)return i; /*找到内存中有该页面,返回BLOCK中位置*/ return -1;}int findReplace(void){int pos = 0,i;for(i=0; i<Bsize; i++)if(block[i].timer >= block[pos].timer)pos = i; /*找到应予置换页面,返回BLOCK中位置*/ return pos;}void display(void){int i=0;for(i=0; i<Bsize; i++)if(block[i].content != -1)printf("%d\t",block[i].content);printf("\n");}void Optimal(void){int exist,space,position,i,k,j ;for(i=0; i<Psize; i++) {exist = findExist(i);if(exist != -1) {printf("不缺页\n");}else {space = findSpace();if(space != -1) {block[space] = page[i];display();}else {for(k=0; k<Bsize; k++)for(j=i; j<Psize; j++) {if(block[k].content != page[j].content) {block[k].timer = 1000;}else {block[k].timer = j;break;}}position = findReplace();block[position] = page[i];display();}}}}void LRU(void){int exist,space,position,i,k,j ;for(i=0; i<Psize; i++) {exist = findExist(i);if(exist != -1) {printf("不缺页\n");block[exist].timer = -1; /*恢复存在的并刚访问过的BLOCK中页面TIMER为-1*/}else {space = findSpace();if(space != -1) {block[space] = page[i];display();}else {position = findReplace();block[position] = page[i];display();}}for(j=0; j<Bsize; j++)block[j].timer++;}}void FIFO(void){int exist,space,position,i,k,j ;for(i=0; i<Psize; i++) {exist = findExist(i);if(exist != -1) {printf("不缺页\n");}else {space = findSpace();if(space != -1) {block[space] = page[i];display();}else {position = findReplace();block[position] = page[i];display();}}for(j=0; j<Bsize; j++)block[j].timer++; /*BLOCK中所有页面TIMER++*/ }}void BlockClear(void) //清空页面信息{int i;for(i=0; i<Bsize; i++) {block[i].content = -1;block[i].timer = 0;}}main(void){int select=1;while(select) {printf("页面置换算法演示程序\n");printf("运行环境RedHat Linux 9 gcc\n");printf("==================\n");printf("页面号引用串:7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1\n");printf("==================\n");printf("请按以下菜单选择:\n");printf("[1]\tOptimal\t算法\n");printf("[2]\tFIFO\t算法\n");printf("[3]\tLRU\t算法\n");printf("[0]\t退出\n");PRA();scanf("%d",&select);switch(select) {case 0:break;case 1:printf("Optimal算法结果如下:\n");Optimal();break;case 2:printf("FIFO算法结果如下:\n");FIFO();break;case 3:printf("LRU算法结果如下:\n");LRU();break;default:printf("菜选项输入错误,请输入(1,2,3,0)\n");break;}BlockClear();}}运行结果:[root@redlinux ys]# gcc page.c -o page.o[root@redlinux ys]# ./page.o==================页面号引用串:7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1==================请按以下菜单选择:[1] Optimal 算法[2] FIFO 算法[3] LRU 算法[0] 退出1↙最佳(Optimal)算法结果如下:77 07 0 12 0 1不缺页2 0 3不缺页2 4 3不缺页不缺页2 0 3不缺页不缺页2 0 1 不缺页不缺页不缺页7 0 1 不缺页不缺页。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验原理:
在内存运行过程中,若其所要访问的页面不在内存而需要把他们调入内存,但内存已经没有空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送磁盘的对换区中。
但应将那个页面调出,需根据一定的算法来确定。
通常,把选择换出页面的算法成为页面置换算法。
置换算法的好坏,将直接影响到系统的性能。
一个好的页面置换算法,应具有较低的页面更换频率。
从理论上讲,应将那些以后不再会访问的页面置换出,或者把那些在较长时间内不会在访问的页面调出。
目前存在着许多种置换算法(如FIFO,OPT,LRU),他们都试图更接近理论上的目标。
实验目的:
1.熟悉FIFO,OPT和LRU算法
2.比较三种算法的性能优劣
实验内容:
写出FIFO,OPT和LRU算法的程序代码,并比较它们的算法性能。
实验步骤:
代码如下:
#include <stdio.h>
#define M 4 //物理页数
#define N 20 //需要调入的页数
typedef struct page
{
int num;
int time;
//物理页项,包括调入的页号和时间}Page;
Page mm[M]; //4个物理页
int queue1[20],queue2[20],queue3[20];//记录置换的页
int K=0,S=0,T=0;
//置换页数组的标识
int pos=0;//记录存在最长时间项
//初始化内存页表项及存储内存情况的空间
. . . .
void INIT(){
int i;
for(i=0;i<M;i++){
mm[i].num =-1;
mm[i].time =0;
}
}
取得内存中存在时间最久的位置//int GetMax(){
int max=-1;
int i;
for(i=0;i<M;i++){
if(mm[i].time > max){
max=mm[i].time ;
pos=i;
}
}
return pos;
}
检查最长时间不使用页面//int longesttime(int fold)
{
int i;
int max=-1;
for(i=fold;i<N;i++){
if(mm[0].num!=i){
mm[0].time++;
}
if(mm[1].num!=i){
mm[1].time++;
. . . . }
if(mm[2].num!=i){
mm[2].time++;
}
if(mm[3].num!=i){
mm[3].time++;
}
}
for(i=0;i<M;i++){
if(mm[i].time>max){
max=mm[i].time;
pos=i;
}
}
return pos;
}
//检查某页是否在内存
int Equation(int fold){
int i;
for(i=0;i<M;i++){
if(mm[i].num == fold)
return i;
}
return -1;
}
//检查物理内存是否已满,-1表满,其他不满int Check(){
int i;
for(i=0;i<M;i++){
if(mm[i].num == -1)
. . . .
return i;
}
return -1;
}
//先进先出
void FIFO(int fold){
int i;
int a,b,c;
a=Equation(fold);
//页已存在
if(a != -1){}
//页不存在
else{
b=Check();
// 内存还有空闲
if(b != -1){
mm[b].num = fold;
}
// 内存已满,需要置换
else {
c=GetMax();
mm[c].num = fold;
mm[c].time = 0;
}
queue1[K++]=fold;
}
for(i=0;i<M;i++){
if(mm[i].num != -1){
mm[i].time ++;
}
. . . . }
}
void OPT(int fold)
{
int a,b,c;
a=Equation(fold);
if(a == -1){//页不在内存
b=Check();
//内存还有空闲
if(b != -1){
mm[b].num = fold;
}
内存已满,需要置换//
else{
c=longesttime(fold);
mm[c].num = fold;
mm[c].time = 0;
}
queue3[T++]=fold;
}
}
void LRU(int fold)
{
int i;
int a,b;
int p;
a=Equation(fold);
if(a != -1)//页已在内存{
. . . . //把此项移动到链表最后一项
if(a==3)// 此项已经在最后,不需要做任何改动
return;
else
{
p=Equation(-1);
if(p==-1)// 链表是满的
{
for(;a<3;a++)
mm[a].num=mm[a+1].num;
mm[3].num=fold;
}
else if(p<=3)// 链表不满
{
for(;a<p-1;a++)
mm[a].num=mm[a+1].num;
mm[a].num=fold;
}
}
}
else
{
b=Check();
if(b!=-1)//不满
mm[b].num=fold;
else
{
for(i=0;i<3;i++)
mm[i].num=mm[i+1].num;
mm[3].num=fold;
. . . . }
queue2[S++]=fold;
}
}
void main()
{
int A[N],B[N];
int i;
INIT();
牰湩晴尨请依次输入%d个页面号:\n,N);
for(i=0;i<N;i++){
scanf(%d,&A[i]);
}
//FIFO
for(i=0;i<N;i++){
B[i]=A[i];
}
for(i=0;i<N;i++){
FIFO( B[i] );
}
); printf(FIFO的); 调入队列为:牰湩晴尨
for(i=0;i<K;i++)
printf(=,queue1[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,K,(float)K/N);
//LRU
INIT();
for(i=0;i<N;i++){
B[i]=A[i];
}
. . . . for(i=0;i<N;i++){
LRU( B[i] );
}
); printf(LRU的
); 牰湩晴尨调入队列为:for(i=0;i<S;i++)
printf(=,queue2[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,S,(float)S/N);
//OPT
INIT();
for(i=0;i<N;i++){
B[i]=A[i];
}
for(i=0;i<N;i++){
OPT( B[i] );
}
); printf(OPT的
); 调入队列为:牰湩晴尨for(i=0;i<T;i++)
printf(=,queue3[i]);
printf(\
缺页次数为:m\n缺页率:_x0016_.6f\n\n,T,(float)T/N);
}
. . . .。