OS实验3的代码和readme

本文档详细介绍了虚拟存储实验的实现,包括FIFO和LRU两种页面置换算法。实验通过模拟进程的内存分配、页面调入调出和数据缓冲,展示了页面置换过程。在页面置换中,当内存满时,FIFO算法会选择最早进入内存的页面牺牲,而LRU算法则选择最近最少使用的页面。此外,还讨论了交换空间在页面调度中的作用,以及如何利用交换空间提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

虚拟存储实验README


代码:

#include <iostream>
using namespace std;

#define Num 10         //进程执行需要的页面数量
#define Len 5          //为进程分配的物理帧数
int M = Len - 1;       //M表示内存中缓冲帧指针
int N = 0;             //N表示内存中下一个牺牲帧的地址
int Exchange[2 * Len]; //交换空间,其中存放换出的地址序列
int Sum = 0;           //Sum表示交换空间中的页面数量
int method = 1;        //使用的算法,此处默认为FIFO

class Memory //进程内存的数据结构
{
public:
    int page;   //物理内存中存放的页号
    bool valid; //有效无效位;无效为0,有效为1
    bool dirty; //修改为:未修改过为0,修改过为1
    Memory()
    {
        page = 0;
        valid = 0;
        dirty = 0;
    }
};

Memory memory[Len]; //为进程分配的内存空间

class Process //进程相关的数据
{
public:
    int page;
    bool write;
    int times;
    Process()
    {
        page = 0;
        write = 0;
        times = 0;
    }
};

Process Page[Num]; //进程运行中需要的页面号与相关操作

void display(int num)
{
    cout << "\n____________________________这是第" << num << "次页面分配________________________\n"
         << endl;
    cout << "当前内存中帧   对应的页面号    脏位:" << endl;
    for (int i = 0; i < Len; i++)
        if (memory[i].valid == 1 && i != M)
            cout << i << "\t\t" << memory[i].page << "\t\t" << memory[i].dirty << endl;
    cout << "\n当前缓冲区的位置" << endl;
    cout << M << endl;
    cout << "\n当前交换空间中页面号" << endl;
    for (int i = 0; i < Sum; i++)
        cout << Exchange[i] << "  ";
    cout << "\n\n\n\n"
         << endl;
}

void set_method()
{
    while (1)
    {
        cout << "选择一种页面置换算法:\n*按下1选择FIFO算法\n*按下2选择LRU算法" << endl;
        cin >> method;
        if (method > 0 && method < 3)
            return;
        else
            continue;
    }
}

void CreatPage()
{
    cout << "\n该进程在运行过程中需要的目标序列与读写操作" << endl;
    for (int i = 0; i < Num; i++)
    {
        Page[i].page = rand() % Num;
        Page[i].write = rand() % 2; //当前情况下为读写页面
    }
    cout << "\n随机生成的内存引用串\n"
         << endl;
    for (int i = 0; i < Num; i++)
    {
        cout << "引用页码:" << Page[i].page << "  "
             << "读写操作:" << Page[i].write << "\n";
        if (i == Num - 1)
        {
            cout << endl;
        }
    }
}

bool search(int a, int &c)
{
    for (c = 0; c < Len; c++)
        if (memory[c].valid == 1 && memory[c].page == a)
            return true;
    return false;
}

bool exchange(int a, int &e)
{
    for (e = 0; e < Sum; e++)
        if (Exchange[e] == a)
            return true;
    return false;
}

bool full(int &n)
{
    //检查内存中的有效无效位,如果存在无效位且不为缓冲区,则未满
    for (n = 0; n < Len; n++)
        if (memory[n].valid == 0 && M != n)
        {
            return false;
        }
    return true;
}

int LRU()
{
    int min = 0, mintime = Page[memory[0].page].times;
    for (int i = 0; i < Len; i++)
    {
        if (Page[memory[i].page].times < mintime)
        {
            mintime = Page[memory[i].page].times;
            min = i;
        }
    }
    return min;
}

int main()
{
    system("chcp 65001");
    set_method();
    CreatPage();
    //读取内存引用串,模拟页面调度过程
    for (int i = 0; i < Num; i++)
    {
        //输出当前内存引用
        cout << "进程执行需要的页面号:\t" << Page[i].page;
        if (Page[i].write)
            cout << "\t写" << endl;
        else
            cout << "\t读" << endl;
        int c;
        //查询是否命中
        if (search(Page[i].page, c))
        {
            cout << "\n命中当前页面" << endl;
            cout << "当前页面:\t" << Page[i].page << "\t在内存的位置:\t" << c << endl;
            if (Page[i].write)
                memory[c].dirty = 1;
            Page[memory[c].page].times++;
            //判断当前页面是读,还是写
        }
        //未命中,开始页面置换
        else
        {
            cout << "\n未命中当前页面" << endl;
            int e;
            //检查所需要的页面是否位于交换空间中
            if (exchange(Page[i].page, e))
            {
                cout << "当前页面处于交换空间中" << endl;
                //放出交换空间中的页面,同时调整交换空间的各页面
                for (int i = e; i < Sum - 1; i++)
                {
                    Exchange[i] = Exchange[i + 1];
                }
                Sum--;
                //Page[memory[c].page].times++;
            }
            int n;
            //检查当前内存是否已经占满,若没有,直接加入内存
            if (!full(n))
            {
                memory[n].page = Page[i].page;
                memory[n].valid = 1;
                if (Page[i].write)
                    memory[n].dirty = 1;
                else
                    memory[n].dirty = 0;
                Page[memory[n].page].times++;
            }
            //内存已满,需要页面置换
            else
            {
                //根据所选用的算法决定换出的页面
                switch (method)
                {
                //先进先出算法
                case 1:
                {
                    memory[M].page = Page[i].page;
                    memory[M].valid = 1;
                    if (Page[i].write)
                        memory[M].dirty = 1;
                    else
                        memory[M].dirty = 0;
                    M = N;
                    N = (N + 1) % Len;
                    memory[M].valid = 0;
                    if (memory[M].dirty == 0 && Sum < 2 * Len)
                    {
                        Exchange[Sum] = memory[M].page;
                        Sum++;
                    }
                }
                break;
                //LRU页面置换
                case 2:
                {
                    memory[M].page = Page[i].page;
                    memory[M].valid = 1;
                    if (Page[i].write)
                        memory[M].dirty = 1;
                    else
                        memory[M].dirty = 0;
                    N = LRU();
                    M = N;
                    memory[M].valid = 0;
                    Page[memory[M].page].times++;
                    if (memory[M].dirty == 0 && Sum < 2 * Len)
                    {
                        Exchange[Sum] = memory[M].page;
                        Sum++;
                    }
                }
                break;
                default:
                    break;
                }
            }
        }
        //输出内存信息
        display(i);
    }
    system("pause");
    return 0;
}

虚拟存储实验README

1、完成虚拟存储的思路

* 基本功能:页面置换、数据缓冲、交换文件

* 页面置换:当为进程分配的内存帧不足时,需要按照页面置换的策略将一个页面进行换入换出操作

* 数据缓冲:系统保留一个空闲帧缓冲池,发生缺页错误在写出之前,所需页面就读到缓冲池的空闲帧,牺牲页面的帧被设定为新的空闲帧

* 交换文件:虚拟内存将不常使用的页面换出至交换空间,提高页面置换的效率

2、进程执行的基本思路

* 在内存中为进程分配了固定的内存空间;(其中包括一个空闲帧作为数据缓冲)

* 进程逐步执行对应的页面,如果页面不在内存中(发生缺页错误),就将其调入内存;如果可用的内存帧为0,就采用调入调出(页面置换)

* 注意对应进程执行的页面,需区分读、写,涉及到脏位与交换空间

* 数据缓冲buffer:在换入换出的过程中,可以先将目的页面换入数据缓冲中,并将选定的牺牲帧设定为空闲空间(已换出)

3、是用什么数据结构模拟虚拟内存调页?

用结构体模拟物理内存和逻辑内存,以全局变量模拟缓冲区和交换空间。

页表和物理外存,在本次实验中由于只有一个进程所以省略,以数组的下标关系取代表示。

4、FIFO算法和LRU算法。

FIFO:当物理内存已满,且请求调页时,取最早进入内存的帧牺牲。

LRU:当物理内存已满,且请求调页时,取最近最少使用的帧牺牲。

5、交换空间 交换空间是专门用于临时存储内存的一块磁盘空间,通常在页面调度和交换进程数据时使用,通常推荐交换空间的大小应该是物理内存的二到四倍。

当可执行程序开始运行时,它的映象会一页一页地从磁盘中换入,与此类似,当某些内存在一段时间内空闲,就可以把它们换出到交换空间中,这样就可以把空闲的RAM交给其他需要它的程序使用。在换入换出的过程中,可以将空闲帧中牺牲掉的帧放到交换空间中,提高读取速度

6、页面置换的基本思路:

* 随着指令的执行,如果发现目标页面不位于当前帧中,发生缺页中断;

* 首先对目的页面进行判断,判断其是否在交换空间中,若在则无需访问文件系统

* 接下来将目标页面调入数据缓冲的帧中,并寻找牺牲帧,将其设定为数据缓冲的帧;

* 最后在这个过程中,对牺牲页面脏位进行判定,如果其未被修改,则将其放置交换空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值