操作系统实验二-虚拟存储器/内存管理(二)

简介: 操作系统实验二-虚拟存储器/内存管理

2.完整代码

FIFO.cpp

#include<stdlib.h>
#include<iostream>
using namespace std;
const int blocklen = 128;
const int M = 4;//主存页面数
const int N = 12;//指令数
int m = 4;
int n = 12;
int k = 0;//FIFO的指针
const int PageSize = 7;//作业需要的页面数
int pageSize = 7;
struct PAGE {
  int flag;//标志
  int blockNum;//主存块号
  int diskPos;//在磁盘上位置
  int editFlag;//修改标志
  PAGE() {
    flag = blockNum = diskPos = editFlag = 0;
  }
};
int P[M];//主存
struct instruct {
  string op;//操作
  int pageNum;//页号
  int unitNum;//单元号
  void print() {
    cout << "Operation:" << op << " Page num:" << pageNum << "  Unit num:" << unitNum << endl;
  }
  instruct(string _op="",int _pageNum=0,int _unitNum=0 ) {
    op = _op;
    pageNum = _pageNum;
    unitNum = _unitNum;
  }
};
instruct inst[105];
PAGE page[105];
void input() {//手动输入
  cout << "input the size of pages in main storage:";
  cin >> m; 
  cout << "input the size of pages of the process:";
  cin >> pageSize;
  cout << "input the number of instructions:";
  cin >> n;
  for (int i = 0; i < m; i++) {
    cout << "input flag,blockNum,diskPos:";
    int flag, blocknum, diskpos;
    cin >> flag>>blocknum>>diskpos;
    page[i].flag = flag;
    if (flag == 1) {
      P[k] = i;
      k = (k + 1) % m;
    }
    page[i].blockNum = blocknum;
    page[i].diskPos = diskpos;
  }
  for (int i = 0; i < n; i++) {
    cout << "input operation,pagenum,unitnum:";
    string op;
    int pagenum, unitnum;
    cin >> op;
    cin >> pagenum >> unitnum;
    inst[i] = { op,pagenum,unitnum };
  }
  k = 0;
  return;
}
void init() {//输入实验指导书上内容
  page[0].flag = 1;
  page[0].blockNum = 5;
  page[0].diskPos = 011;
  page[1].flag = 1;
  page[1].blockNum = 8;
  page[1].diskPos = 012;
  page[2].flag = 1;
  page[2].blockNum = 9;
  page[2].diskPos = 013;
  page[3].flag = 1;
  page[3].blockNum = 1;
  page[3].diskPos = 021;
  page[4].diskPos = 022;
  page[5].diskPos = 023;
  page[6].diskPos = 121;
  inst[0] = { "+",0,70 };
  inst[1] = { "+",1,50 };
  inst[2] = { "*",2,15 };
  inst[3] = { "save",3,21 };
  inst[4] = { "get",0,56 };
  inst[5] = { "-",6,40 };
  inst[6] = { "move",4,53 };
  inst[7] = { "+",5,23 };
  inst[8] = { "save",1,37 };
  inst[9] = { "get",2,78 };
  inst[10] = { "+",4,1 };
  inst[11] = { "save",6,84 };
  P[0] = 0;
  P[1] = 1;
  P[2] = 2;
  P[3] = 3;
}
void interrupt(int L) {//中断处理
  int j = P[k];//要调出的页面
  if (page[j].editFlag == 1)
    cout << "out J!" << j << endl;//调出当前页
  page[j].flag = 0;
  cout << "in L" << L << endl;//调入页面
  P[k] = L;
  k = (k + 1) % m;
  page[L].flag = 1;//将页装入主存
}
void cpuwork() {
  for (int i = 0; i < n; i++) {
    int L = inst[i].pageNum;//取指令中访问的页号
    inst[i].print();
    if (page[L].flag == 1) {//查页表
      int addr = page[L].blockNum * blocklen + inst[i].unitNum;//输出绝对地址
      if (inst[i].op == "save")//是否为存指令
        page[L].editFlag = 1;
      cout << "absolute address:" << addr << endl;
    }
    else {
      cout << "******interrupt!*****\n";
      interrupt(L);
      i--;//重新查页表
    }
    cout << "********************************\npages in main storage\n";
    for (int i = 0; i <m; i++)
      cout << "Page num:" << P[i] << " Block num:" << page[P[i]].blockNum << " Edit Flag:" << page[P[i]].editFlag
      <<" Disk pos:" << page[P[i]].diskPos <<endl;
    cout << "********************************\n\n"
cout << "********************************\npages of the work\n";
    for (int i = 0; i <pageSize; i++)
      cout << "Page num:" << i <<" flag:" <<page[i].flag<<" Block num:" << page[i].blockNum << " Edit Flag:" << page[i].editFlag
      <<" Disk pos:" << page[i].diskPos <<endl;
    cout << "********************************\n\n";
  }
}
int main() {
  int choose;
  cout << "Choose input:1. auto 2.by hand";
  cin >> choose;
  if (choose == 1)
    init();
  else
    input();
  cpuwork();
}

LRU.cpp

#include<stdlib.h>
#include<iostream>
using namespace std;
const int blocklen = 128;
const int M = 4;//主存页面数
const int N = 12;//指令数
int m = 4;
int n = 12;
int k = 0;//FIFO的指针
const int PageSize = 7;//作业需要的页面数
int pageSize = 7;
struct PAGE {
  int flag;//标志
  int blockNum;//主存块号
  int diskPos;//在磁盘上位置
  int editFlag;//修改标志
  PAGE() {
    flag = blockNum = diskPos = editFlag = 0;
  }
};
int P[50];//主存
struct instruct {
  string op;//操作
  int pageNum;//页号
  int unitNum;//单元号
  void print() {
    cout << "Operation:" << op << " Page num:" << pageNum << "  Unit num:" << unitNum << endl;
  }
  instruct(string _op = "", int _pageNum = 0, int _unitNum = 0) {
    op = _op;
    pageNum = _pageNum;
    unitNum = _unitNum;
  }
};
instruct inst[105];
PAGE page[105];
void input() {
  cout << "input the size of pages in main storage:";
  cin >> m;
  cout << "input the size of pages of the process:";
  cin >> pageSize;
  cout << "input the number of instructions:";
  cin >> n;
  for (int i = 0; i < m; i++) {
    cout << "input flag,blockNum,diskPos:";
    int flag, blocknum, diskpos;
    cin >> flag >> blocknum >> diskpos;
    page[i].flag = flag;
    if (flag == 1) {
      P[k] = i;
      k = (k + 1) % m;
    }
    page[i].blockNum = blocknum;
    page[i].diskPos = diskpos;
  }
  for (int i = 0; i < n; i++) {
    cout << "input operation,pagenum,unitnum:";
    string op;
    int pagenum, unitnum;
    cin >> op;
    cin >> pagenum >> unitnum;
    inst[i] = { op,pagenum,unitnum };
  }
  k = 0;
  return;
}
void init() {//实验指导书上的页表
  page[0].flag = 1;
  page[0].blockNum = 5;
  page[0].diskPos = 011;
  page[1].flag = 1;
  page[1].blockNum = 8;
  page[1].diskPos = 012;
  page[2].flag = 1;
  page[2].blockNum = 9;
  page[2].diskPos = 013;
  page[3].flag = 1;
  page[3].blockNum = 1;
  page[3].diskPos = 021;
  page[4].diskPos = 022;
  page[5].diskPos = 023;
  page[6].diskPos = 121;
  inst[0] = { "+",0,70 };
  inst[1] = { "+",1,50 };
  inst[2] = { "*",2,15 };
  inst[3] = { "save",3,21 };
  inst[4] = { "get",0,56 };
  inst[5] = { "-",6,40 };
  inst[6] = { "move",4,53 };
  inst[7] = { "+",5,23 };
  inst[8] = { "save",1,37 };
  inst[9] = { "get",2,78 };
  inst[10] = { "+",4,1 };
  inst[11] = { "save",6,84 };
  P[0] = 0;
  P[1] = 1;
  P[2] = 2;
  P[3] = 3;
}
void interrupt(int L) {//中断服务
  int j = P[m - 1];//栈底页面调出
  if (page[j].editFlag == 1)
    cout << "out J!" << j << endl;//调出该页面
  page[j].flag = 0;
  cout << "in L" << L << endl;
  P[3] = P[2];
  P[2] = P[1];
  P[1] = P[0];
  P[0] = L;//调整主存中的页面
  page[L].flag = 1;
}
void cpuwork() {
  for (int i = 0; i < n; i++) {
    int L = inst[i].pageNum;//取指令访问的页号
    inst[i].print();
    if (page[L].flag == 1) {
      int addr = page[L].blockNum * blocklen + inst[i].unitNum;//形成绝对地址
      if (inst[i].op == "save")
        page[L].editFlag = 1;
      cout << "absolute address:" << addr << endl;
      int pos = 0;//调整主存中的页面
      for (int i = 1; i <m; i++) {
        if (P[i] == L) {
          pos = i;
          break;
        }
      }
      if(pos!=0)
        for (int i = pos; i >= 1; i--)
          P[i] = P[i - 1];
      P[0] = L;
    }
    else {
      cout << "******interrupt!*****\n";
      interrupt(L);
      i--;
    }
    cout << "********************************\npages in main storage\n";
    for (int i = 0; i < m; i++)
      cout << "Page num:" << P[i] << " Block num:" << page[P[i]].blockNum << " Edit Flag:" << page[P[i]].editFlag
      << " Disk pos:" << page[P[i]].diskPos << endl;
    cout << "********************************\n\n";
cout << "********************************\npages of the work\n";
    for (int i = 0; i <pageSize; i++)
      cout << "Page num:" << i <<" flag:" <<page[i].flag<<" Block num:" << page[i].blockNum << " Edit Flag:" << page[i].editFlag
      <<" Disk pos:" << page[i].diskPos <<endl;
    cout << "********************************\n\n";
  }
}
int main() {
  int choose;
  cout << "Choose input:1. auto 2.by hand";
  cin >> choose;
  if (choose == 1)
    init();
  else
    input();
  cpuwork();

(4)程序运行结果

 打印初始页表,每次调出(要调出一页时)和装入的页号,执行最后一条指令后在主存中的页面号(即数组的值)。

FIFO算法

 图为初始页表,与实验指导书是完全一致的。

 执行到第5条指令,调出第0页时,装入了第6页。因为修改标志位为0,所以不必将“0”调出并输出。

 执行到第6条指令,调出第1页时,装入了第4页。因为修改标志位为0,所以同样不必将“1”调出并输出。

 执行到第7条指令,调出第2页时,装入了第5页。因为修改标志位为0,所以同样不必将“2”调出并输出。

 执行到第8条指令,调出第3页时,装入了第1页。因为修改标志位为1,所以需要将“3”输出。

 执行到第9条指令,调出第6页时,装入了第2页。因为修改标志位为0,所以同样不必将“6”调出并输出。

 执行到最后一条指令,调出第4页时,装入了第6页。因为修改标志位为0,所以同样不必将“4”调出并输出。同时,图10也是执行完最后一条指令时主存中的页面号。

LRU算法

 图为初始页表,无论采用哪种算法,其与实验指导书是完全一致的。

 图为第一次中断时,将数组底部的1调出,将6调入。并修改栈内情况。

 图为第二次中断时,将数组底部的2调出,将4调入。并修改栈内情况。

 图为第三次中断时,将数组底部的3调出,将5调入。并修改栈内情况。由于3的修改标志位为1,所以需要将3输出。

 图为第四次中断时,将数组底部的0调出,将1调入。并修改栈内情况。

 图为第五次中断时,将数组底部的6调出,将2调入。并修改栈内情况。

 图为第六次中断时,将数组底部的5调出,将6调入。并修改栈内情况。

 全部指令运行完成后,留在主存中的页面号。

五、思考题

 如果你有兴趣的话,可把两种页面调度算法都做一下,比较两种调度算法的效率(哪种调度算法产生缺页中断的次数少);分析在什么情况下采用哪种调度算法更有利?

 如上文,已实现并运行两种页面调度算法。其中,FIFO算法产生了6次缺页中断,缺页中断率为6/12=50%。LRU算法产生了6次缺页中断,缺页中断率为6/12=50%。对于实验指导书给的数据,两种算法效率相同。缺页中断次数相同在大多数情况下尤其是执行循环语句时,LRU算法更有利。

六、实验感悟

目录
相关文章
|
6天前
|
存储 缓存
操作系统的虚拟内存管理机制
在现代计算机系统中,虚拟内存是一种至关重要的内存管理技术。它允许操作系统使用硬盘空间来扩展物理内存容量,从而支持更多并发运行的程序。本文将深入探讨虚拟内存的概念、实现方式以及其在操作系统中的作用和重要性。
|
5天前
|
存储 算法
探索现代操作系统中的虚拟内存管理技术
在数字时代的浪潮中,操作系统的心脏——虚拟内存管理技术,正以它独有的韵律跳动。本文将带你穿梭于操作系统的迷宫,揭开虚拟内存如何巧妙地扩展有限的物理内存之谜。从分页机制的精妙设计到交换空间的策略运用,我们将一探究竟。你将看到,虚拟内存不仅仅是一个存储数据的地方,它是速度与效率的协调者,是多任务处理的幕后英雄。随着技术的演进,虚拟内存管理不断优化,为应用程序提供了一片更为广阔的运行天地。让我们一同走进这个充满智慧的世界,感受操作系统中虚拟内存管理的魅力所在。
13 1
|
8天前
|
缓存 算法 Linux
深入理解操作系统的内存管理机制
【6月更文挑战第23天】内存管理是操作系统中一个至关重要的功能,它直接影响到系统性能和资源利用效率。本文旨在深入探讨现代操作系统中内存管理的核心概念、关键技术以及面临的挑战。通过分析内存管理的基本原理、内存分配策略、虚拟内存技术、缓存管理和内存安全等方面,揭示内存管理在提升操作系统稳定性、安全性与高效性方面的作用。文章将结合具体操作系统实例,如Windows、Linux等,阐述不同内存管理技术的实现细节和优化策略,为读者提供对操作系统内存管理机制全面而深刻的认识。
19 3
|
10天前
|
存储 缓存 算法
探索现代操作系统的虚拟内存管理机制
【6月更文挑战第21天】在数字时代的浪潮中,操作系统作为计算机系统的核心,其设计和管理策略直接影响着计算效率和用户体验。本文将深入探讨现代操作系统中的虚拟内存管理机制,包括其工作原理、实现方式及其对系统性能的影响。通过分析虚拟内存技术如何优化资源分配、提高多任务处理能力及对硬件资源的抽象管理,揭示其在现代操作系统中的重要性和应用价值。
|
8天前
|
存储 缓存 算法
深入理解操作系统:从进程管理到内存优化
【6月更文挑战第23天】在数字化时代,操作系统是支撑计算设备的心脏。本文将探索操作系统的核心组件,着重于进程管理和内存优化策略,揭示它们如何共同确保系统资源的高效利用和任务的顺畅执行。通过分析现代操作系统的设计哲学和技术实现,本文旨在为读者提供对操作系统内部工作原理的深刻洞察,并展示其对提高计算性能和用户体验的重要性。
|
12天前
|
算法
深入理解操作系统中的虚拟内存管理
【6月更文挑战第19天】在现代操作系统中,虚拟内存管理是一个至关重要的组件。它不仅使得程序能够在有限的物理内存中运行更大的地址空间,还为系统提供了多任务处理能力。本文将深入探讨虚拟内存的概念、实现机制以及它在操作系统中的重要性,同时也会讨论虚拟内存管理中遇到的挑战和解决方案。
19 4
|
12天前
|
存储 算法
深入理解操作系统的内存管理机制
【6月更文挑战第19天】本文旨在探讨现代操作系统中内存管理的关键技术和策略,分析其对系统性能及稳定性的影响。通过介绍分页、分段、虚拟内存等概念,揭示操作系统如何有效管理物理与虚拟内存资源,以及这些技术在多任务处理和内存保护方面的应用。文章将重点讨论内存泄漏、碎片整理和页面置换算法等高级主题,以期为读者提供对内存管理复杂性及其解决方案的深刻理解。
14 2
|
12天前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
|
2天前
|
存储 算法 调度
深入理解操作系统:虚拟内存管理的艺术
【6月更文挑战第29天】在数字世界的无限风光背后,隐藏着一个不为人知的复杂世界——操作系统。本文将揭开操作系统中最为精妙的设计之一——虚拟内存管理的神秘面纱,从基础概念出发,逐步探索其背后的原理与实现机制。我们将通过生动的比喻和实例,带领读者领略虚拟内存如何在有限的物理资源上创造出无限的可能,以及它如何优化系统性能,提升用户体验。准备好了吗?让我们一同潜入操作系统的心脏,一探究竟。
|
5天前
|
存储 缓存 算法
深入理解操作系统:从进程管理到内存分配
本文深入探讨操作系统的核心组件,特别关注进程管理和内存分配机制。通过分析现代操作系统中这两个关键领域的设计原理和实现技术,文章揭示了它们如何共同确保系统资源的有效利用和任务的高效执行。我们将从理论到实践,逐步解析进程状态变迁、调度算法以及内存分配策略,旨在为读者提供对操作系统内部工作原理的深刻见解。
6 0