操作系统实验——页面置换算法

最佳页面置换(OPT)算法: 这是一种理想情况下的页面置换算法,但实际上不可能实现。基本思想是应该淘汰最近的未 来最久不再使用的页。

先进先出(FIFO)算法 当需要选择一个页面淘汰时,总是选择最先进入内存空间的那一个页面。只要在系统中建立 一个 FIFO 队列,以反映页面的活动情况。被选择的页面总是处于队首的页面,而最近调入的页 面永远存放在队列的尾部。

最近最久未使用(LRU)算法 该算法的基本思想是用最近的过去估计最近的将来。假定在内存中某个页面,在最近一段时 间内未被使用的时间最长,那么在最近的将来也可能不再被使用。 

#include<iostream> 
#include<bits/stdc++.h>
using namespace std;
int n;
int L;
void OPT(int arr[], int n, int L, int miss[]){
	int miss_count=0;//缺页次数
	int change_count=0;//置换次数 
	int arr_i[n][L];//记录内存块中页号情况
    memset(arr_i,-1,sizeof(arr_i));
	//实现OPT算法
	for(int i=0;i<L;i++){
		int page=arr[i]; // 获取当前要访问的页面号
		int null_index=-1;//获取空内存块号 
		bool found=false;// 标记物理块中是否已经存在该页面
		bool judge=false;//判断内存块是否已满 
		if(i>0){         //更新 i 列 物理块 
			for(int j=0;j<n;j++){
				arr_i[j][i]=arr_i[j][i-1];
		    }
		}
		for(int j=0;j<n;j++){
			if(arr_i[j][i]==page){
				found=true;// 如果已经存在,则标记为true
				miss[i]=0;//缺页标记为 0  
				break;
			}
		}
		// 如果页面不存在于物理块中,进行页面置换 
		//判断内存块是否已满 
		for(int j=0;j<n;j++){
			if(arr_i[j][i] == -1){
				judge=true;// 如果内存块未满,则标记为true 
				null_index=j;//记录空块号 
				break;
			}
		}
		if(!found&&judge){//缺页且内存块未满 
			arr_i[null_index][i]=page;
			miss[i]=1; //缺页标记 1  
			cout<<"内存块未满,加入页号:"<<page<<endl;
			miss_count++;
		}
		if(!found&&!judge){//缺页且内存块满 
			int maxdist = -1; // 最长时间不被访问的页面距离
			int maxindex = -1;// 最长时间不被访问的页面位置
			
			// 遍历物理块数组,找出最长时间不被访问的页面
            for (int j = 0; j < n; j++) {
                int dist = 0; // 记录当前页面距离下一次访问的距离               
                for (int k = i + 1; k < L; k++) {//从page下一页开始遍历 
                    if (arr_i[j][i] == arr[k]) {//寻找内存块 j 出现的距离 
                        dist = k - i;
                        break;
                    }
                    else if(k==L-1){
                    	dist=L-1;
					}
                }
                //如果当前页面距离下一次访问的距离大于已经找到的最长距离,则更新
                if(dist > maxdist){
                	maxdist=dist;
                	maxindex=j;
				}
		    }
		    //打印置换详情 
		    change_count++;	
		    cout<<endl<<"发生页面置换,序号:"<<change_count<<endl;
		    cout<<"换出:"<<arr_i[maxindex][i]<<endl<<"换入:"<<page<<endl<<"换出内存块号:"<<maxindex+1<<endl;
		     // 将找到的最长时间不被访问的页面替换为当前页面
			arr_i[maxindex][i]=page;
			// 标记缺页	
			miss[i]=1;
			miss_count++;
			    
	    } 
    } 
	
	
	 
	cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;
	cout << "\t\t\t最佳页面置换算法OPT" << endl << endl;
	cout<<"页面号\t";//输出页面号详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<arr[i];
	}
	cout<<endl;
	for(int i=0;i<n;i++){//输出块号详情 
		cout<<"块"<<i+1<<"\t";
		for(int j=0;j<L;j++){
			cout<<std::setw(6)<<std::right<<arr_i[i][j];
		}
		cout<<endl; 
	}
	cout<<"缺页\t";//输出缺页详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<miss[i];
	}
	cout<<endl<<"缺页次数:"<<miss_count<<endl;
	cout<<"置换次数:"<<change_count<<endl; 
	cout<<"缺页率:"<<(float)(miss_count)/L*100<<"%"<<endl;
	cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;
}
void FIFO(int arr[],int n,int L,int miss[]){
	memset(miss,0,sizeof(miss));//重置miss数组 
	int miss_count=0;//缺页次数
	int change_count=0;//置换次数 
	int arr_i[n][L];//记录内存块中页号情况
	int index=0;//记录换出内存块号 
    memset(arr_i,-1,sizeof(arr_i));//初始化内存块表
		for(int i=0;i<L;i++){
		int page=arr[i]; // 获取当前要访问的页面号
		int null_index=-1;//获取空内存块号 
		bool found=false;// 标记物理块中是否已经存在该页面
		bool judge=false;//判断内存块是否已满 
		if(i>0){         //更新 i 列 物理块 
			for(int j=0;j<n;j++){
				arr_i[j][i]=arr_i[j][i-1];
		    }
		}
		for(int j=0;j<n;j++){
			if(arr_i[j][i]==page){
				found=true;// 如果已经存在,则标记为true
				miss[i]=0;//缺页标记为 0  
				break;
			}
		}
		// 如果页面不存在于物理块中,进行页面置换 
		//判断内存块是否已满 
		for(int j=0;j<n;j++){
			if(arr_i[j][i] == -1){
				judge=true;// 如果内存块未满,则标记为true 
				null_index=j;//记录空块号 
				break;
			}
		}
		if(!found&&judge){//缺页且内存块未满 
			arr_i[null_index][i]=page;
			miss[i]=1; //缺页标记 1  
			cout<<"内存块未满,加入页号:"<<page<<endl;
			miss_count++;
		}
		
		if(!found&&!judge){//缺页且内存块满 
		    //打印置换详情 
		    
		    if(index > n-1){
		    	index=0;
			}
		    change_count++;	
		    cout<<endl<<"发生页面置换,序号:"<<change_count<<endl;
		    cout<<"换出:"<<arr_i[index][i]<<endl<<"换入:"<<page<<endl<<"换出内存块:"<<index+1<<endl;
		     // 将内存块 index 页面替换为当前页面
			arr_i[index][i]=page;
			// 标记缺页	
			index++;//更新置换块号  
			miss[i]=1;
			miss_count++;
			    
	    } 
    }  
	
	cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;
	cout << "\t\t\t先入先出算法FIFO" << endl << endl;
	cout<<"页面号\t";//输出页面号详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<arr[i];
	}
	cout<<endl;
	for(int i=0;i<n;i++){//输出块号详情 
		cout<<"块"<<i+1<<"\t";
		for(int j=0;j<L;j++){
			cout<<std::setw(6)<<std::right<<arr_i[i][j];
		}
		cout<<endl; 
	}
	cout<<"缺页\t";//输出缺页详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<miss[i];
	}
	cout<<endl<<"缺页次数:"<<miss_count<<endl;
	cout<<"置换次数:"<<change_count<<endl; 
	cout<<"缺页率:"<<(float)(miss_count)/L*100<<"%"<<endl;
	cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;
}
void LRU(int arr[],int n,int L,int miss[]){
	memset(miss,0,sizeof(miss));//重置miss数组 
	int miss_count=0;//缺页次数
	int change_count=0;//置换次数 
	int arr_i[n][L];//记录内存块中页号情况
	int time[n]={0};
	memset(arr_i,-1,sizeof(arr_i));//初始化内存块表
	for(int i=0;i<L;i++){
		int page=arr[i]; // 获取当前要访问的页面号
		int null_index=-1;//获取空内存块号 
		bool found=false;// 标记物理块中是否已经存在该页面
		bool judge=false;//判断内存块是否已满
		if(i>0){         //更新 i 列 物理块 
			for(int j=0;j<n;j++){
				arr_i[j][i]=arr_i[j][i-1];
		    }
		}
		for(int j=0;j<n;j++){
			int index;//判断是否跳出 循环 
			if(arr_i[j][i]==page){
				found=true;// 如果已经存在,则标记为true
				index=j;
				miss[i]=0;//缺页标记为 0 
				
			}
			if(found){
				for(int j=0;j<n;j++){
					time[j]++;
				}
				time[index]=0;
				break;				
			} 
		}
		// 如果页面不存在于物理块中,进行页面置换 
		//判断内存块是否已满 
		
		for(int j=0;j<n;j++){
			if(arr_i[j][i] == -1){
				judge=true;// 如果内存块未满,则标记为true 
				null_index=j;//记录空块号 
				break;
			}
		}
		if(!found&&judge){//缺页且内存块未满 
			arr_i[null_index][i]=page;
			miss[i]=1; //缺页标记 1  
			cout<<"内存块未满,加入页号:"<<page<<endl;
			miss_count++;
			for(int k=0;k<=null_index;k++){
				if(k==null_index){
					time[k]=0;
				}
				else{
					time[k]++;
				}
			}
		}
		
		if(!found&&!judge){//缺页且内存块满 
		    int maxtime=-1;
		    int maxindex=-1; 
		    for(int j=0;j<n;j++){    //寻找最久未使用页号 所在块 
		    	if(time[j]>maxtime){
		    		maxtime=time[j];
		    		maxindex=j;
				}				
			}
			//arr_i[maxindex][i]=page;//置换			
			for(int j=0;j<n;j++){   //更新 time表 
				time[j]++;
			} 
		    time[maxindex]=0;		    		    
		    //打印置换详情 
		    change_count++;	
		    cout<<endl;
		    for(int j=0;j<n;j++){
		    	cout<<time[j]<<" ";
			}
			cout<<endl;
		    cout<<endl<<"发生页面置换,序号:"<<change_count<<endl;
		    cout<<"换出:"<<arr_i[maxindex][i]<<endl<<"换入:"<<page<<endl<<"换出内存块:"<<maxindex+1<<endl;
		     // 将内存块 index 页面替换为当前页面
			arr_i[maxindex][i]=page;
			// 标记缺页	  
			miss[i]=1;
			miss_count++;
			    
	    } 
    }
    
    cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;
	cout << "\t\t\t最久未使用算法LRU" << endl << endl;
	cout<<"页面号\t";//输出页面号详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<arr[i];
	}
	cout<<endl;
	for(int i=0;i<n;i++){//输出块号详情 
		cout<<"块"<<i+1<<"\t";
		for(int j=0;j<L;j++){
			cout<<std::setw(6)<<std::right<<arr_i[i][j];
		}
		cout<<endl; 
	}
	cout<<"缺页\t";//输出缺页详情 
	for(int i=0;i<L;i++){
		cout<<std::setw(6)<<std::right<<miss[i];
	}
	cout<<endl<<"缺页次数:"<<miss_count<<endl;
	cout<<"置换次数:"<<change_count<<endl; 
	cout<<"缺页率:"<<(float)(miss_count)/L*100<<"%"<<endl;
	cout << "---------------------------------------------------------------------------------------------------------------------------------" << endl;

} 




int main(){
	
	cout << "请输入物理块的数量:";
	cin>>n;
	
	cout << "请输入要访问的页面数量:";
	cin>>L;
	cout<<endl; 
	//int arr1[L]={7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3,2,1,2,0,1,7,0,1};//页面号序列 
	//int arr2[L]={3,2,1,0,3,2,4,3,2,1,0,4};
	//int arr3[L]={1,8,1,7,8,2,7,2,1,8,3,8,2,1,3,1,7,1,3,7}; 
	int miss[L]={0};//缺页数组,记录缺页情况
	int arr[L];
	srand(time(0));
	for(int i=0;i<L;i++){
		arr[i]=rand()%9+1;
	}

	OPT(arr,n,L,miss);
	FIFO(arr,n,L,miss);
	LRU(arr,n,L,miss);
	cout<<endl<<endl;
	return 0;
} 

注:一起交流一起学习,发托市玩玩,🤡🤡

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值