操作系统分页式存储管理

这篇博客探讨了操作系统中分页式存储管理的FIFO、LRU和OPT三种算法。在处理地址时,根据页号判断是否越界,并分别实现各算法的缺页与命中情况。FIFO遵循先进先出原则,LRU则是最近最少使用。当栈满时,FIFO和LRU会进行置换操作。OPT算法则寻找未来最久不使用的页面进行置换。文章通过模拟栈来展示这些过程,并在最后详细记录了每种算法的结果。
摘要由CSDN通过智能技术生成

每次输入地址后,计算出页号,若页号越界,则给出错误提示。否则依次调用FIFO和LRU算法,这里值得注意的是,由于我们的FIFO算法先于LRU算法被调用,那么当在处理FIFO算法时,我们暂且不将位视图相应位置做变化,留到处理LRU算法再做处理。

对于FIFO、LRU算法的缺页,我们分两种情况考虑,第一种是模拟栈内还有空间,那么直接将其入栈。第二种是模拟栈内无空间,要发生置换。发生置换时把模拟栈最底的弹出,新来的加入栈顶。

对于FIFO、LRU算法的命中,二者不同之处就是对于LRU算法,当元素命中时,要将该元素移至栈顶。

对于OPT算法,每次置换时向后查找,与栈内未来最久不使用的进行置换,若无法找到最久不使用的元素,那么默认与栈底元素进行置换。

回填位视图时只要对FIFO页表或LRU页表进行扫描,找到状态为true的位置,将其在位视图中对应的位置置回原值即可。

对于三种算法的输出格式,只要开三个相对应的二维数组,然后每次按照格式对二维数组进行赋值即可。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <time.h>
#include <string>
#include <algorithm>
#include <deque>
#include <queue>
using namespace std;

int N , M;
#define Length 4132
const int maxn = 101;

struct Page
{
    int id;
    int block;
    bool stau;
};

struct Page page_fifo[maxn] , page_lru[maxn] , page_opt[maxn];

int fifo[maxn];
int inva_fifo;

int lru[maxn];
int inva_lru;

int opt[maxn];
int inva_opt;
int cols;

int fifo_2[maxn][maxn] , lru_2[maxn][maxn] , opt_2[maxn][maxn];

bool view[maxn];

int address[maxn];
int add_len;

void out_rate_fifo()
{
    system("cls");
    cout << "FIFO缺页率 : ";
    cout << inva_fifo  << "/" << add_len << endl;
    cout << endl;
    system("PAUSE");
}

void out_rate_lru()
{
    system("cls");
    cout << "LRU缺页率 : ";
    cout << inva_lru  << "/" << add_len << endl;
    cout << endl;
    system("PAUSE");
}

void out_rate_opt()
{
    system("cls");
    cout << "OPT缺页率 : ";
    cout << inva_opt  << "/" << add_len << endl;
    cout << endl;
    system("PAUSE");
}

void out_pageFifo()
{
    system("cls");
    cout << "页表(FIFO):" << endl;
    for(int i = 0 ; i < M ; i ++)
        cout << page_fifo[i].id << " " << page_fifo[i].block << " " << page_fifo[i].stau << endl;
    cout << endl;
    system("PAUSE");
}


void out_pageLru()
{
    system("cls");
    cout << "页表(LRU):" << endl;
    for(int i = 0 ; i < M ; i ++)
        cout << page_lru[i].id << " " << page_lru[i].block << " " << page_lru[i].stau << endl;
    cout << endl;
    system("PAUSE");
}


void out_address()
{
    for(int i = 0 ; i < add_len ; i ++)
        cout << address[i] << " ";
    cout << endl;
    cout << "----------------------------------------------" << endl;
}


void out_allFifo()
{
    system("cls");
    cout << "FIFO置换过程" << endl;
    out_address();
    for(int i = 0 ; i < N ; i ++)
    {
        for(int j = 0 ; j < add_len ; j ++)
        {
            if(fifo_2[i][j] == -1)
                cout << "  ";
            else
                cout << fifo_2[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
    system("PAUSE");
}

void out_allLru()
{
    system("cls");
    cout << "LRU置换过程" << endl;
    out_address();
    for(int i = 0 ; i < N ; i ++)
    {
        for(int j = 0 ; j < add_len ; j ++)
        {
            if(lru_2[i][j] == -1)
                cout << "  ";
            else
                cout << lru_2[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
    system("PAUSE");
}


void out_allOpt()
{
    system("cls");
    cout << "OPT置换过程" << endl;
    out_address();
    for(int i = 0 ; i < N ; i ++)
    {
        for(int j = 0 ; j < add_len ; j ++)
        {
            if(opt_2[i][j] == -1)
                cout << "  ";
            else
                cout << opt_2[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
    system("PAUSE");
}

void out_view()
{
    system("cls");
    cout << "位示图:" << endl;
    int cnt = 1;
    for(int i = 0 ; i < 64 ; i ++)
    {
        cout << (view[i] == true ? "1" : "0");
        cout << ((cnt++) % 8 == 0 ? "\n" : " ");
    }
    cout << endl;
    system("PAUSE");
}

void re_view()
{
    for(int i = 0 ; i < M ; i ++)
        if(page_fifo[i].stau)
            view[page_fifo[i].block] = false;
    out_view();
}

void trans_fifo()
{
    int cnt = 0;
    for(int i = N - 1 ; i >= 0 ; i --)
        fifo_2[cnt++][add_len - 1] = fifo[i];
}

void trans_lru()
{
    int cnt = 0;
    for(int i = N - 1 ; i >= 0 ; i --)
        lru_2[cnt++][add_len - 1] = lru[i];
}

void trans_opt()
{
    int cnt = 0;
    for(int i = N - 1 ; i >= 0 ; i --)
        opt_2[cnt++][cols] = opt[i];
    cols ++;
}

void OPT()
{
    inva_opt = 0 , cols = 0;
    for(int i = 0 ; i < N ; i ++)   opt[i] = -1;
    for(int k = 0 ; k < add_len ; k ++)
    {
        int index = address[k] , go = 0;
        for(int i = 0 ; i < N ; i ++)
        {
            if(opt[i] == index)
            {
                go = 1;
                break;
            }
        }
        if(go)
        {
            trans_opt(); continue;
        }
        inva_opt ++;
        int pos = 0 , flag = 0 , pos2 = 0;
        for(int i = 0 ; i < 64 ; i ++)
            if(!view[i])    { pos = i; break;}
        for(int i = 0 ; i < N ; i ++)
            if(opt[i] == -1)    { pos2 = i; flag = 1; break; }
        if(flag)
        {
            page_opt[index].block = pos;
            page_opt[index].stau = true;
            opt[pos2] = page_opt[index].id;
            //view[pos] = true;
        }
        else
        {
            bool vis[maxn] = { false };
            int cnt = 0 , poskey = 0;
            for(int i = k + 1 ; i < add_len ; i ++)
            {
                for(int j = 0 ; j < N ; j ++)
                {
                    if(address[i] == opt[j] && vis[j] == false)
                    {
                        vis[j] = true;
                        cnt ++;
                    }
                }
                if(cnt == N - 1)
                    break;
            }
            for(int i = 0 ; i < N ; i ++)
                if(!vis[i]) { poskey = i ; break; }
            int old_pos = opt[poskey];
            page_opt[old_pos].stau = false;
            page_opt[index].block = page_opt[old_pos].block;
            page_opt[index].stau = true;
            page_opt[old_pos].block = -1;
            opt[poskey] = index;
        }
        trans_opt();
    }
}


void FIFO(int index)
{
    if(page_fifo[index].stau == true)
        { trans_fifo(); return; }
    int pos = 0 , flag = 0 , pos2 = 0;
    for(int i = 0 ; i < 64 ; i ++)
        if(!view[i])    { pos = i; break;}
    for(int i = 0 ; i < N ; i ++)
        if(fifo[i] == -1)   { pos2 = i; flag = 1; break;}
    inva_fifo ++;
    if(flag)
    {
        page_fifo[index].block = pos;
        page_fifo[index].stau = true;
        fifo[pos2] = page_fifo[index].id;
        //view[pos] = true;
    }
    else
    {
        // FIFO置换
        int old_pos = fifo[0];
        page_fifo[old_pos].stau = false;
        page_fifo[index].block = page_fifo[old_pos].block;
        page_fifo[index].stau = true;
        page_fifo[old_pos].block = -1;
        for(int i = 0 ; i < N ; i ++)
            if(i + 1 < N)   fifo[i] = fifo[i+1];
        fifo[N-1] = index;
    }
    trans_fifo();
}


void LRU(int index)
{

    if(page_lru[index].stau == true)
    {
        // LRU置换
        int pos = 0;
        for(int i = 0 ; i < N ; i ++)
            if(lru[i] == index)    { pos = i; break; }
        int temp = lru[pos];
        for(int i = pos ; i < N ; i ++)
            if(i + 1 < N)   lru[i] = lru[i+1];  else    break;
        lru[N-1] = temp;
        trans_lru();
        return;
    }
    int pos = 0 , flag = 0 , pos2 = 0;
    for(int i = 0 ; i < 64 ; i ++)
        if(!view[i])    { pos = i; break;}
    for(int i = 0 ; i < N ; i ++)
        if(lru[i] == -1)   { pos2 = i; flag = 1; break;}
    inva_lru ++;
    if(flag)
    {
        page_lru[index].block = pos;
        page_lru[index].stau = true;
        lru[pos2] = page_lru[index].id;
        view[pos] = true;
    }
    else
    {
        int old_pos = lru[0];
        page_lru[index].stau = true;
        page_lru[index].block = page_lru[old_pos].block;
        page_lru[old_pos].block = -1;
        page_lru[old_pos].stau = false;
        for(int i = 0 ; i < N ; i ++)
            if(i + 1 < N)   lru[i] = lru[i+1];
        lru[N-1] = index;
    }
    trans_lru();
}


void input()
{
    system("cls");
    cout << "请输入地址 :" << endl;
    int key;
    scanf("%x",&key);
    int index = key / Length;
    if(index >= M)
        cout << "页号越界错误!" << endl;
    else
    {
        address[add_len++] = index;
        FIFO(index);
        LRU(index);
    }
    cout << endl;
    system("PAUSE");
}


void creat()
{
    srand(time(NULL));
    int cnt = 0;
    for(int i = 0 ; i < 64 ; i ++)
    {
        int temp = rand() % 100 + 1;
        if(temp % 2 == 0)
        {
            view[i] = false;
            cnt ++;
        }
        else
            view[i] = true;
    }
    if(cnt < M)
        creat();
}

void init()
{
    for(int i = 0 ; i < M ; i ++)
    {
        page_fifo[i].id = i; page_lru[i].id = i;    page_opt[i].id = i;
        page_fifo[i].block = -1; page_lru[i].block = -1;    page_opt[i].block = -1;
        page_fifo[i].stau = false;   page_lru[i].stau = false;  page_opt[i].stau = false;
    }
    for(int i = 0 ; i < N ; i ++)   { fifo[i] = -1; lru[i] = -1; opt[i] = -1;}
    add_len = 0;
    inva_fifo = 0;
    inva_lru = 0;
}

void menu()
{
    cout << "\t\t\t*******************************" << endl;
    cout << "\t\t\t\t欢迎登陆DoubleQ的操作系统" << endl;
    cout << "\t\t\t*******************************" << "\n\n";
    cout << "\t\t\t1.查位视图" << endl;
    cout << "\t\t\t2.查看FIFO页表" << endl;
    cout << "\t\t\t3.查看LRU页表" << endl;
    cout << "\t\t\t4.查看FIFO表" << endl;
    cout << "\t\t\t5.查看LRU表" << endl;
    cout << "\t\t\t6.查看OPT表" << endl;
    cout << "\t\t\t7.查看FIFO缺页率" << endl;
    cout << "\t\t\t8.查看LRU缺页率" << endl;
    cout << "\t\t\t9.查看OPT缺页率" << endl;
    cout << "\t\t\t10.查看回填位视图" << endl;
    cout << "\t\t\t11.输入地址" << endl;
    cout << "\t\t\t12.退出" << endl;
    cout << "\t\t\t";
}

void solve()
{
    int poss , kuai;
    cout << "请输入进程大小(单位:KB) : " << endl;
    cin >> poss;
    cout << "请输入每页大小(单位:KB)" << endl;
    cin >> kuai;
    M = poss / kuai + (poss % kuai != 0 ? 1 : 0);
    cout << "请输入内存分配多少块 : " << endl;
    cin >> N;
    system("PAUSE");
    system("cls");
    init();
    creat();
    bool flag = true;
    while(flag)
    {
        menu();
        int sel;    cin >> sel;
        switch(sel)
        {
        case 1:
            out_view(); break;
        case 2:
            out_pageFifo(); break;
        case 3:
            out_pageLru(); break;
        case 4:
            out_allFifo(); break;
        case 5:
            out_allLru();  break;
        case 6:
            OPT();  out_allOpt();  break;
        case 7:
            out_rate_fifo();    break;
        case 8:
            out_rate_lru(); break;
        case 9:
            OPT(); out_rate_opt(); break;
        case 10:
            re_view(); break;
        case 11:
            input(); break;
        case 12:
            exit(0);
        }
        system("cls");
    }
}

int main()
{
    solve();
    return 0;
}


### 回答1: 分页存储管理操作系统中一种常见的内存管理方,它将进程的逻辑地址空间划分为固定大小的页,将物理内存划分为与之相等的物理页框,通过页表实现逻辑页与物理页之间的映射关系。在实验中,我们可以使用Java编程语言模拟分页存储管理的过程。 首先,我们需要定义一个页表类,用于记录逻辑页号和物理页号之间的映射关系。该类可以包含一个哈希表或数组,以逻辑页号作为键,物理页号作为值。 接下来,需要编写一个模拟程序,模拟进程的内存访问过程。该程序可以随机生成一个逻辑地址,然后通过页表查找该逻辑地址对应的物理页号。如果页表中存在该逻辑页号的映射关系,程序就可以通过物理页号找到相应的物理内存地址;否则,程序需要进行页面置换算法来选择一个物理页进行替换,并更新页表中的映射关系。 在实验中,可以选择常见的页面置换算法,如最近最久未使用(LRU)、先进先出(FIFO)、钟算法(CLOCK)等,来模拟操作系统的页面置换过程。根据选择的算法,我们可以编写相应的替换函数来实现物理页的选择和替换。 总之,通过实现一个页表类和模拟程序,我们可以模拟分页存储管理的过程,并通过选择适当的页面置换算法来实现页的替换操作。该实验可以帮助我们更好地理解操作系统中的内存管理机制,并加深对分页存储管理的理解。 ### 回答2: 操作系统分页存储管理是计算机操作系统中的一个重要概念,它涉及到内存中数据的存储和管理。在分页存储管理中,内存被划分为固定大小的页框,每个页面大小相同。而程序的数据则被划分为多个大小相等的页面,每个页面被映射到内存中的一个页框。通过这种方,程序的逻辑地址可以被划分为页号和偏移量,而不需要关心实际的物理地址。 在这个实验中,我们可以用Java编写一个简化的分页存储管理系统模拟。我们可以通过以下几个步骤来完成这个实验: 1. 定义页面和页框的大小。例如,我们可以将页面和页框大小都定义为4KB,即4096字节。 2. 定义程序的逻辑地址空间和物理地址空间。逻辑地址空间可以分为页号和偏移量,而物理地址空间则直接对应着内存中的页框。 3. 实现页面的映射和置换算法。页面的映射可以通过一个页表来实现,存储页面到页框的映射关系。如果内存中的页框已经被占用,需要使用置换算法将某些页面置换出去,腾出页框给新的页面。 4. 实现页面访问和管理功能。通过逻辑地址,我们可以找到对应的页号和偏移量,然后根据页表的映射关系找到物理地址。页面的访问可以是读取或写入操作。 通过这个实验,我们可以深入理解分页存储管理的原理并且学习如何使用Java来模拟实现这个功能。这有助于我们更好地理解操作系统中内存的管理和存储机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值