《操作系统存储管理》

实验二:存储管理

一、 实验目的:

  1. 通过编写程序实现请求分页存储管理的Optimal、FIFO、LRU等页面置换算法中的一种,掌握虚拟存储管理中有关缺页处理方法等内容,巩固有关虚拟存储管理的教学内容。
  2. 理解内存分配原理,特别是以页面为单位的虚拟内存分配方法。

关于操作系统的内存管理,如何节省利用容量不大的内存为最多的进程提供资源,一直是研究的重要方向。而内存的虚拟存储管理,是现在最通用,最成功的方式—— 在内存有限的情况下,扩展一部分外存作为虚拟内存,真正的内存只存储当前运行时所用得到信息。这无疑极大地扩充了内存的功能,极大地提高了计算机的并发度。虚拟页式存储管理,则是将进程所需空间划分为多个页面,内存中只存放当前所需页面,其余页面放入外存的管理方式。

置换算法有:最佳置换算法OPT、FIFO置换算法、最少使用页面置换算法、最近未使用页面置换算法、时钟页面置换算法等

三、 实验环境

基于win10x64位操作系统    

操作平台:DEV

四、 实验内容

通过简单的程序模拟多种存储管理算法,通过输入页面访问序列,查页表等操作判别是否缺页,按照FIFO、LRU两种算法淘汰页面,并调入所访问的页面,打印输入、输出结果,在程序中,0代表为空,*代表缺页,并计算缺页率。

FIFO算法:FIFO( First In First Out)简单说就是指先进先出,是内存管理的一种页面置换算法。按照页面装进内存的时间进行置换,老的页面最先被换出,不管该页面是否经常使用,这样就有可能导致缺页率增加,导致页面置换次数增加。

LRU是Least Recently Used 近期最少使用算法。该算法按照上次使用时间进行排序,将离上次使用时间最长的页面换出。可以采用栈的数据结构,每次页面被访问将该页面号放在栈顶。也可使用移位寄存器实现:设置引用位R,每次调用将R=1,系统每个一段时间将R=0,当进行置换式检查哪个页面为零说明近期不会再使用,可以将其换出。

五、 设计实现

  1. 流程图

FIFO流程图:

LRU流程图:

  1. 代码设计

#include <iostream>

#include<set>

#include <algorithm>

#include<cstdio>

#include <windows.h>

#include <conio.h>

#define N 200

using namespace std;

int page[N];//页面引用号

int block[N];//物理块

int dist[N][N];//表示第i次访问内存的时候,内存中的页面j 在以后被访问的最小时间

int pnum;//页面号数

int bnum;//物理块数

int page_max;//最大页面号

int pre[N];//page[i]在page中的索引

set<int>page_set;

int fifo() {//先进先出页面置换算法

int page_lack = 0;

memset(block, -1, sizeof(block));

int index = 1;

cout<<"fifo算法开始"<<endl<<endl;

for (int i = 1; i <= pnum; ++i) {

if (index > bnum) index = 1; //开始下一轮循环

set<int>::iterator it;

it = page_set.find(page[i]);

cout << "第"<<i<<"次访问,页为"<<page[i]<< endl;

if (it == page_set.end()) //没有找到page[i]项

{

cout << "页面" << page[i] << "不在表中,放入页号为" << index << "的表项中" << endl;

if (block[index] != -1) //如果物理块不为空,则先清除,再替换

page_set.erase(block[index]);

page_set.insert(page[i]);

block[index++] = page[i];

++page_lack;

}

else

{

cout << "已存在并查到第" << page[i] << "页"  << endl;

}

cout << "显示当前页面分配情况" << endl;

cout<<"| ";

for (int k = 1; k <= bnum; ++k)

{

if (block[k] != -1)

{

if (k == bnum)

{

cout << block[bnum] << " |" << endl << endl;

}

else

{

cout << block[k] << " | ";

}

}

else

{

if (k == bnum)

{

cout << "  | " << endl << endl;

}

else

{

cout << "  | ";

}

}

}

}

printf("缺页次数:%d    缺页率:%.2f    命中率:%.2f\n", page_lack, (float)page_lack / pnum, 1.0 - (float)page_lack / pnum);

return page_lack;

}

int lru() { //最近最久未使用页面淘汰法

int page_lack = 0;

memset(pre, 0, sizeof(pre));

memset(dist, 0x3f, sizeof(dist));

memset(block, -1, sizeof(block));

for (int i = 1; i <= pnum; ++i) {

for (int j = 0; j <= page_max; ++j)

if (pre[j])

dist[i][j] = i - pre[j];//当前轮次数减去上次存在的轮次

pre[page[i]] = i;//存在i的当前轮次

}

for (int i = 1; i <= pnum; ++i) {

for (int j = 0; j <= page_max; ++j)

cout << "dist["<<i<<"]["<<j<<"]" << dist[i][j]<<endl;

}

for (int i = 1; i <= pnum; ++i)

{

cout << "pre["<<i<<"]" << pre[i]<<endl;

}

cout << "lru算法开始" << endl << endl;

for (int i = 1; i <= pnum; ++i) {//开始访问页面,初始是内存中没有分页

int j;

int max_dist = 0, p;

for (j = 1; j <= bnum; ++j)  //所有物理块均为空,将前bnum个页面填入表。改块没有放入页面,则直接放入, 产生缺页

{

if (block[j] == -1) {

block[j] = page[i];

cout << "页面" << page[i] << "表中,放入页号为" << j << "的表项中" << endl;

page_lack++;

break;

}

else if (block[j] == page[i])//页面存在内存中

{

cout << endl;

cout << "已存在并查到第" << page[i] << "页在第" << j << "块" << endl;

break;

}

if (max_dist < dist[i][block[j]]) {

max_dist = dist[i][block[j]];//说明block[j] 对应的页面以后会长时间不会用到

p = j;//block[] 第j个页面会被替换掉

}

}

if (j > bnum) {//此时内存中不能在放入新的分页,而且没有找到page[i]对应的分页,接下来进行页面替换

cout << "页面" << page[i] << "表中,放入页号为" << p << "的表项中" << endl;

block[p] = page[i];

page_lack++;

}

cout << endl << "当前内存中页面的情况:" << endl;

for (int k = 1; k <= bnum; ++k)

{

if (block[k] != -1)

{

if (k == bnum)

{

cout << block[bnum] << " |" << endl << endl;

}

else

{

cout << block[k] << " | ";

}

}

else

{

if (k == bnum)

{

cout << "  | " << endl;

}

else

{

cout << "  | ";

}

}

}

}

printf("缺页次数:%d    缺页率:%.2f    命中率:%.2f\n", page_lack, (float)page_lack / pnum, 1.0 - (float)page_lack / pnum);

return page_lack;//返回缺页次数

}

int main() {

int c;

cout << "--------------页面置换算法-------------" << endl;

cout << "---------------页面个数:-------------" << endl;

cin >> pnum;

cout << "--------------物理块数目:------------" << endl;

cin >> bnum;

cout << "-------请输入" << pnum << "个页面号:---------" << endl;

for (int i = 1; i <= pnum; ++i) {

cin >> page[i];

page_max = max(page_max, page[i]);

}

while (true)

{

cout << "1:FIFO先进先出算法" << endl;  //先进先出 算法

cout << "2:LRU最近最久未使用页面淘汰算法" << endl;  //最近最久未使用页面淘汰 算法

cout << "0:结束" << endl;

cout << "请选择页面置换算法:" << endl;

cin>>c;

switch (c)

{

case 1:

cout << "缺页中断次数:" << fifo() << endl;

printf("按任意键继续\n");

system("PAUSE");

if(!_kbhit())

{

system("cls");

}

break;

case 2:

cout << "缺页中断次数:" << lru() << endl;

printf("按任意键继续\n");

system("PAUSE");

if (!_kbhit())

{

system("cls");

}

break;

case 0:

exit(0);

default:

system("cls");

cout << "没有与输入相匹配的操作,请重新输入" << endl;

}

}

return 0;

}

六、 实验结果

  1. FIFO先进先出算法实验结果

7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 1 7 0 1

FIFO算法开始

第1次访问,页为7

页面7不在表中,放入页号为1的表项中

显示当前页面分配情况

| 7 |   |   |

第2次访问,页为0

页面0不在表中,放入页号为2的表项中

显示当前页面分配情况

| 7 | 0 |   |

第3次访问,页为1

页面1不在表中,放入页号为3的表项中

显示当前页面分配情况

| 7 | 0 | 1 |

第4次访问,页为2

页面2不在表中,放入页号为1的表项中

显示当前页面分配情况

| 2 | 0 | 1 |

第5次访问,页为0

已存在并查到第0页

显示当前页面分配情况

| 2 | 0 | 1 |

第6次访问,页为3

页面3不在表中,放入页号为2的表项中

显示当前页面分配情况

| 2 | 3 | 1 |

第7次访问,页为0

页面0不在表中,放入页号为3的表项中

显示当前页面分配情况

| 2 | 3 | 0 |

第8次访问,页为4

页面4不在表中,放入页号为1的表项中

显示当前页面分配情况

| 4 | 3 | 0 |

第9次访问,页为2

页面2不在表中,放入页号为2的表项中

显示当前页面分配情况

| 4 | 2 | 0 |

第10次访问,页为3

页面3不在表中,放入页号为3的表项中

显示当前页面分配情况

| 4 | 2 | 3 |

第11次访问,页为0

页面0不在表中,放入页号为1的表项中

显示当前页面分配情况

| 0 | 2 | 3 |

第12次访问,页为3

已存在并查到第3页

显示当前页面分配情况

| 0 | 2 | 3 |

第13次访问,页为2

已存在并查到第2页

显示当前页面分配情况

| 0 | 2 | 3 |

第14次访问,页为1

页面1不在表中,放入页号为2的表项中

显示当前页面分配情况

| 0 | 1 | 3 |

第15次访问,页为2

页面2不在表中,放入页号为3的表项中

显示当前页面分配情况

| 0 | 1 | 2 |

第16次访问,页为0

已存在并查到第0页

显示当前页面分配情况

| 0 | 1 | 2 |

第17次访问,页为1

已存在并查到第1页

显示当前页面分配情况

| 0 | 1 | 2 |

第18次访问,页为1

已存在并查到第1页

显示当前页面分配情况

| 0 | 1 | 2 |

第19次访问,页为7

页面7不在表中,放入页号为1的表项中

显示当前页面分配情况

| 7 | 1 | 2 |

第20次访问,页为0

页面0不在表中,放入页号为2的表项中

显示当前页面分配情况

| 7 | 0 | 2 |

第21次访问,页为1

页面1不在表中,放入页号为3的表项中

显示当前页面分配情况

| 7 | 0 | 1 |

缺页次数:15    缺页率:0.71    命中率:0.29

缺页中断次数:15

 

  1. LRU近期最少使用算法实验结果

 

 

七、 实验过程中出现的问题及解决办法

页面置换算法是操作系统中与进程调用同样重要的一部分,意义在于能够将使用较频繁的项目保存在页表中,便于快速的执行应用程序等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
实验目的】 1. 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解; 2. 熟悉虚存管理的各种页面淘汰算法; 3. 通过编写和调试地址转换过程的模拟程序以加强对地址转换过程的了解。 【实验准备】 1.虚拟存储器的管理方式  段式管理  页式管理  段页式管理 2.页面置换算法  先进先出置换算法  最近最久未使用置换算法  Clock置换算法  其他置换算法 【实验内容】 1. 实验题目 设计一个请求页式存储管理方案。并编写模拟程序实现之。产生一个需要访问的指令地址流。它是一系列需要访问的指令的地址。为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得 50%的指令是顺序执行的。25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分。为简单起见。页面淘汰算法采用 FIFO页面淘汰算法,并且在淘汰一页时,只将该页在页表中抹去。而不再判断它是否被改写过,也不将它写回到辅存。 2. 具体做法 产生一个需要访问的指令地址流;指令合适的页面尺寸(例如以 1K或2K为1页);指定内存页表的最大长度,并对页表进行初始化;每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按 FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光而不耀-2001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值