计算机操作系统实验之页面置换算法(C语言)
实验目的
1、了解内存分页管理策略
2、掌握一些基本的页面置换算法
实验内容与基本要求
用C,C++等语言编写程序,实现OPT、FIFO、LRU置换算法
页面置换算法的基本内容
页面置换算法是在当进程运行过程中,若其要访问的页面不在内存且内存已满时,要决定将哪个页面换出的算法。常见的页面置换算法包括最佳置换、先进先出置换、最近最久未使用置换和Clock置换等。本次的实验实现的算法包括最佳置换算法(OPT)、先进先出置换算法(FIFO)和最近最久未使用算法(LRU)。
页面置换算法涉及到一些概念如下:
- 缺页率:当需要访问的页面不在内存时称为缺页,此时需要将页面调入内存。缺页率就是要访问的页面不在内存中的概率。因此缺页率=缺页次数/要访问的页面总数。需要注意的是,缺页的时候不一定需要进行页面置换(如果内存还没满,直接将页面调入内存即可)。
- 置换率:置换就是将旧页面调出内存,新页面调进内存,即新页面代替旧页面的过程。置换率就是需要进行页面置换的概率。所以置换率=置换次数/要访问的页面总数。
- 命中率:就是要访问的页面恰好在内存中的概率。可以发现(缺页率+命中率=1)。
最佳置换算法
最佳置换算法,就是所选择内存中以后永远不再使用,或者是在未来最长的一段时间内不再被访问的页面来换出。
用这种算法可以保证获得最低的缺页率,最低的置换次数,因此效率最高。然而在实际情况中,我们是无法知道哪个页面是未来最长时间内不再被访问的,所以实际上它是无法实现的。
先进先出置换算法
先进先出置换算法,就是选择内存中最先进入内存,在内存中呆的最久的页面来换出。它实现简单,但是效率不高。
最近最久未使用算法
最近最久未使用算法,是选择当前内存中,最久没有被访问的页面来换出。它是希望通过过去页面访问的情况,来预测未来页面的访问情况,但是页面过去与未来的走向之间并没有必然的联系,因此它的效率也不是十分高。
实现思路
无论采用哪个算法,当进程需要访问一个页面时,存在三种情况:
1.页面已经在内存中
2.页面不在内存中,但是此时内存还未满
3.页面不在内存中,且此时内存已满,需要把页面换出
不同算法的区别主要是决定换出哪个页面
最佳置换算法中,被换出的算法是在最长未来时间内不再被访问的页面。也就是说,需要计算出当前内存中页面的下一次访问位置,哪个页面的下一次访问位置最远,就将它换出。因此需要一个数组额外记录下次访问位置,每当访问完一个页面(不管这个页面是新换入的,还是早就在内存中的),都需要遍历剩下的页面号引用串,更新这个数组。
先进先出置换算法比较简单,用一个变量记录当前内存中最先进入页面的下标。由于页面都是按数组下标顺序保存的,因此每访问一个页面,该变量就加一。等变量等于数组长度时,再重新归零即可。
最近最久未使用算法有两种思路:1.与最佳置换算法类似,设置一个时间数组,记录从内存中页面上次访问至今的时间,哪个页面的时间最长则将它换出。如果要访问的页面已在内存中,则时间归零。当每次发起一个访问请求,则所有页面访问时间加一,更新该数组。2.用数组模拟队列的结构,队列头出队列尾入,每当需要访问新的页面时,就将数组内的数据前移一位,新页面加入数组最后。如果要访问的页面已在内存中,则用一个临时变量记录该页面,然后从该页面起的数据前移一位,把该页面加入数组最后(课本上说是用栈的结构,但是严格上来说,栈只允许一端出入。因此按照课本上的功能描述,实际应该采用的结构仍是队列)
流程图
程序总流程图
OPT算法流程图
FIFO算法流程图
LRU算法流程图
全部代码
代码
//
// main.c
// pageReplacement
//
// Created by Apple on 2019/11/12.
// Copyright © 2019 Yao YongXin. All rights reserved.
//
#include <stdio.h>
//初始化队列
void initializeList(int list[],int number){
for (int i = 0; i < number; i ++) {
list[i] = -1;
}
}
//展示队列状态
void showList(int list[], int number){
for (int i = 0; i < number; i ++) {
printf("%2d",list[i]);
}
printf("\n");
}
//展示当前内存状态
void showMemoryList(int list[],int phyBlockNum){
for (int i = 0; i < phyBlockNum; i ++) {
if (list[i] == -1) {
break;
}
printf(" |%d|",list[i]);
}
printf("\n");
}
void informationCount(int missingCount,int replaceCount,int pageNum){
printf("缺页次数:%d 缺页率:%d/%d\n",missingCount,missingCount,pageNum);
double result = (double)(pageNum - missingCount)/(double)pageNum;
printf("置换次数:%d 命中率:%.2f\n",replaceCount,result);
}
//找到该页面下次要访问的位置
int getNextPosition(int currentPage,int currentPosition,int strList[],int pageNum){
for (int i = currentPosition+