精华内容
下载资源
问答
  • 操作系统实验 存储管理 呵呵 我们地实验 交上去地 是doc格式地
  • 计算机操作系统内存管理功能实现存储空间的分配与回收。当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还...
  • 实验存储管理-可变分区存储管理的空间分配与去配 一、实验目的 要求掌握存储管理中的典型算法,理解各种存储管理的工作原理,特别是可变分区存储管理中最先适应分配算法、最优适应分配算法、最坏适应分配算法以及...

    实验四 存储管理-可变分区存储管理的空间分配与去配

    一、实验目的
    要求掌握存储管理中的典型算法,理解各种存储管理的工作原理,特别是可变分区存储管理中最先适应分配算法、最优适应分配算法、最坏适应分配算法以及空间回收算法的工作原理,试采用C语言编程,模拟实现算法功能。

    二、实验要求
    设计一个可变式分区分配的存储管理方案,并模拟实现分区的分配和回收过程。
    假定主存空间为静态分配。为实现分区的分配和回收,需要已分配分区表和系统空闲分区表描述当前系统状态。已分配分区表包括分区编号、已分配分区长度、分区的起始地址等信息。系统空闲分区表包括分区编号、分区长度、分区的起始地址等信息。用户根据需要提出对主存空间大小的申请,系统按照一定的分配策略,找出能满足请求的空闲区进行分配。如果满足要求,输出分配完成后已分配分区表和空闲区表的信息,否则输出“无空闲区分配”。
    用户根据需要释放主存空间,实现空间的回收,并输出空间回收后已分配分区表和空闲区表的信息。

    反正代码是写吐了
    如果要加很多功能的话还可以加
    开源图一乐

    /* 
        时间:4月27日~4月28日
       	仅供参考,还请不要复制粘贴
     */
    
    #include <iostream>
    #include <string>
    #include <queue>
    using namespace std;
    // 分配表最多容纳100个
    #define MAX 100
    
    // 创建进程信息
    struct process
    {
        int seq;
        // 分区表的单行序号
        int length;
        // 分区表的单行长度
        int begin_address;
        // 分区表的起始地址
        int number;
        // 最后哪个进程被分配的进程编号
    };
    
    // 创建可变分区表的结构体,表长和进程信息
    struct system_list
    {
    
        process informationArray[MAX];
        int size;
    };
    
    // 菜单展示
    void display()
    {
        cout << "__________________________________" << endl;
        cout << "__________1.设计空闲区信息__________" << endl;
        cout << "__________2.显示空闲区信息______________" << endl;
        cout << "__________3.添加作业队列信息______________" << endl;
        cout << "__________4.显示作业队列信息______________" << endl;
        cout << "__________5.最先分配适应算法________________" << endl;
        cout << "__________6.最优分配适应算法______________" << endl;
        cout << "__________7.最坏分配适应算法_______________" << endl;
        cout << "__________8.主存回收_______________" << endl;
        cout << "__________0.退出系统______________" << endl;
        cout << "__________________________________" << endl;
    }
    
    void addInfo(system_list *l)
    {
        cout << "下面开始建立空闲分区表" << endl;
    
        int seq;
        cout << "输入空闲分区的分区编号" << endl;
        cin >> seq;
        l->informationArray[l->size].seq = seq;
    
        int length;
        cout << "输入空闲分区的可分配区域长度" << endl;
        cin >> length;
        l->informationArray[l->size].length = length;
    
        int begin_address;
        cout << "输入空闲分区的起始地址(十进制)" << endl;
        cin >> begin_address;
        l->informationArray[l->size].begin_address = begin_address;
    
        l->informationArray[l->size].number = -1;
    
        l->size++;
    }
    void displayInformation(system_list *l)
    {
        if (l->size == 0)
        {
            cout << "当前空闲区不空闲" << endl;
            return;
        }
        else
        {
            for (int i = 0; i < l->size; i++)
            {
                cout << "----------------------------------------------------------------------------------" << endl;
                cout << "空闲区序号: " << l->informationArray[i].seq << "\t";
                cout << "空闲区长度: " << l->informationArray[i].length << "\t";
                cout << "空闲区起始地址: " << l->informationArray[i].begin_address << "\t";
                cout << "分配的进程编号: " << l->informationArray[i].number << endl;
                cout << "----------------------------------------------------------------------------------" << endl;
            }
        }
    }
    
    // 创建作业队列,运用queue标准库
    void pushlist(queue<int> *list)
    {
        cout << "请输入你要设计的作业队列需要的内存:" << endl;
        int num;
        cin >> num;
        list->push(num);
    }
    void displaylist(queue<int> *list)
    {
        cout << "----------------队列内容:------------------" << endl;
        int n = 0;
        int pop;
        while (n < list->size())
        {
            cout << "序号为:" << n << "  需求内存为: " << list->front() << endl;
            list->push(list->front());
            list->pop();
            // 没有遍历器,就在出队的同时入队
            n++;
        }
    }
    
    // 冒泡排序:让地址从低到高排序
    void bubble_address(system_list *l)
    {
        process temp;
        for (int i = 0; i < l->size - 1; i++)
        {
            for (int j = 0; j < l->size - i - 1; j++)
            {
                if (l->informationArray[j].begin_address > l->informationArray[j + 1].begin_address)
                {
                    temp = l->informationArray[j];
                    l->informationArray[j] = l->informationArray[j + 1];
                    l->informationArray[j + 1] = temp;
                }
            }
        }
    }
    // 最先适应分配算法
    void frist_fit_allocated(system_list *l, queue<int> *list)
    {
        // 先将地址进行冒泡排序
        bubble_address(l);
        cout << "++++++++++++++++++++++++++++++分配前的空闲区信息++++++++++++++++++++++++" << endl;
        displayInformation(l);
        int n = 0;
    
        while (n < list->size())
        {
            for (int i = 0; i < l->size; i++)
            {
                if (list->front() <= l->informationArray[i].length && l->informationArray[i].number == -1)
                {
                    l->informationArray[i].length = l->informationArray[i].length - list->front();
                    // 将所剩余的空间显示出来。
                    l->informationArray[i].number = n;
                    // 并且将进程编号放入
                    list->pop();
                    // 删除队首
                    break;
                }
            }
            n++;
        }
        cout << "++++++++++++++++++++++分配后的进程信息++++++++++++++++++===+++" << endl;
        displayInformation(l);
        if ((list->size()) != 0)
        {
            cout << "仍然有作业没有分配到空间,请开始主存回收功能重试" << endl;
            displaylist(list);
        }
    }
    
    // 选择排序,将空闲区容量从低到高排序
    void select_length(system_list *l)
    {
        for (int i = 0; i < l->size; i++)
        {
            for (int j = i + 1; j < l->size; j++)
            {
                if (l->informationArray[i].length > l->informationArray[j].length)
                {
                    swap(l->informationArray[i], l->informationArray[j]);
                }
            }
        }
    }
    // 最优适应分配算法
    void frist_best_allocated(system_list *l, queue<int> *list)
    {
        // address sort the select
        select_length(l);
        cout << "++++++++++++++++++++++++++++++分配前的空闲区信息++++++++++++++++++++++++" << endl;
        displayInformation(l);
        int n = 0;
    
        while (n < list->size())
        {
            for (int i = 0; i < l->size; i++)
            {
                if (list->front() <= l->informationArray[i].length && l->informationArray[i].number == -1)
                {
                    l->informationArray[i].length = l->informationArray[i].length - list->front();
                    // 将所剩余的空间显示出来。
                    l->informationArray[i].number = n;
                    // 并且将进程编号放入
                    list->pop();
                    // 删除队首
                    break;
                }
            }
            n++;
        }
        cout << "++++++++++++++++++++++分配后的进程信息++++++++++++++++++===+++" << endl;
        displayInformation(l);
        if ((list->size()) != 0)
        {
            cout << "仍然有作业没有分配到空间,请开始主存回收功能重试" << endl;
            displaylist(list);
        }
    }
    
    // 冒泡排序,让空闲区容量从高到低
    void fast_length(system_list *l)
    {
        for (int i = 0; i < l->size - 1; i++)
        {
            for (int j = 0; j < l->size - 1 - i; j++)
            {
                if (l->informationArray[j].length < l->informationArray[j + 1].length)
                {
                    swap(l->informationArray[j], l->informationArray[j + 1]);
                }
            }
        }
    }
    void frist_terrible_allocated(system_list *l, queue<int> *list)
    {
        fast_length(l);
        cout << "++++++++++++++++++++++++++++++分配前的空闲区信息++++++++++++++++++++++++" << endl;
        displayInformation(l);
        int n = 0;
    
        while (n < list->size())
        {
            for (int i = 0; i < l->size; i++)
            {
                if (list->front() <= l->informationArray[i].length && l->informationArray[i].number == -1)
                {
                    l->informationArray[i].length = l->informationArray[i].length - list->front();
                    // 将所剩余的空间显示出来。
                    l->informationArray[i].number = n;
                    // 并且将进程编号放入
                    list->pop();
                    // 删除队首
                    break;
                }
            }
            n++;
        }
        cout << "++++++++++++++++++++++分配后的进程信息++++++++++++++++++===+++" << endl;
        displayInformation(l);
        if ((list->size()) != 0)
        {
            cout << "仍然有作业没有分配到空间,请开始主存回收功能重试" << endl;
            displaylist(list);
        }
    }
    
    // 重点来了:主存回收-----------------------------------------------------------
    void retrieve(system_list *l)
    {
        bubble_address(l);
        cout << "地址排序结果" << endl;
        displayInformation(l);
        l->informationArray[l->size].begin_address = -100;
        l->informationArray[l->size + 1].begin_address = -100;
        l->informationArray[l->size + 2].begin_address = -100;
        int i = 1;
        while (l->informationArray[i].begin_address != -100)
        {
            // 上面有空间,下面有空间
            if (l->informationArray[i].begin_address - 1 == l->informationArray[i - 1].begin_address && l->informationArray[i].begin_address + 1 == l->informationArray[i + 1].begin_address && l->informationArray[i].length > 0 && l->informationArray[i + 1].length > 0 && l->informationArray[i - 1].length > 0)
            {
                l->informationArray[i - 1].length += l->informationArray[i].length + l->informationArray[i + 1].length;
                while (2)
                {
                    for (int j = i; j < l->size; j++)
                    {
                        l->informationArray[j] = l->informationArray[j + 1];
                    }
                    l->size--;
                }
            }
    
            // 上面有空间
            else if (l->informationArray[i].begin_address - 1 == l->informationArray[i - 1].begin_address && l->informationArray[i].length > 0 && l->informationArray[i - 1].length > 0)
            {
                l->informationArray[i - 1].length += l->informationArray[i].length;
                for (int j = i; j < l->size; j++)
                {
                    l->informationArray[j] = l->informationArray[j+1];
                }
                l->size--;
            }
            // 下面有空间
            else if (l->informationArray[i].begin_address + 1 == l->informationArray[i + 1].begin_address && l->informationArray[i].length > 0 && l->informationArray[i + 1].length > 0)
            {
                l->informationArray[i - 1].length += l->informationArray[i].length;
                for (int j = i + 1; j < l->size; j++)
                {
                    l->informationArray[j] = l->informationArray[j + 1];
                }
                l->size--;
            }
            i++;
        }
        cout<<"+++++++++++++++++++++++++回收结果++++++++++++++++++++++++++++++++++"<<endl;
        displayInformation(l);
        cout << "没有可以回收的空间啦" << endl;
    }
    
    int main()
    {
        int select = 0;
        system_list l;
        queue<int> list;
        l.size = 0;
        cout << "请输入你的选择" << endl;
        while (true)
        {
    
            display();
            cin >> select;
            switch (select)
            {
                // 1~2输入空闲区信息
            case 1:
            {
                cout << "请按照提示输入信息" << endl;
                int num;
                cout << "请输入你要设定空闲区的个数" << endl;
                cin >> num;
                while (num)
                {
                    addInfo(&l);
                    num--;
                }
                cout << "添加完毕,请开始你的表演吧!" << endl;
            }
            break;
    
            case 2:
            {
                displayInformation(&l);
            }
            break;
    
            // 3~4输入作业队列信息
            case 3:
            {
                cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~开始作业队列的输入~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
                cout << "请按照提示输入信息" << endl;
                int num1;
                cout << "请输入你要设定进入空闲区进程的的个数" << endl;
                cin >> num1;
                while (num1)
                {
                    pushlist(&list);
                    num1--;
                }
                cout << "添加完毕" << endl;
            }
            break;
            case 4:
            {
                displaylist(&list);
            }
            break;
            // 最先适应分配算法。
            case 5:
                frist_fit_allocated(&l, &list);
                break;
            // 最优适应分配算法
            case 6:
                frist_best_allocated(&l, &list);
                break;
            // 最坏适应分配算法
            case 7:
                frist_terrible_allocated(&l, &list);
                break;
            case 8:
                retrieve(&l);
                break;
    
            case 0:
                cout << "不欢迎下次的使用" << endl;
                return 0;
            default:
                break;
            }
        }
    }
    
    
    展开全文
  • 实验的目的是通过请求页式存储管理中页面置换算法模拟设计 了解虚拟存储技术的特点 掌握请求页式管理的页面置换算法 2 实验要求 1 通过随机数产生一个指令序列 共320条指令 指令的地址按下述原则生成: 50%的...
  • 选择功能项(0-退出,1-分配主存,2-回收主存,3-显示主存)\n")
  • 本程序实现操作系统实验 存储管理—动态分区管理 对内存为1024k的内存进行动态分区管理 程序在Dev-c++环境下调试通过
  • 操作系统存储管理实验报告,附代码,及PPT讲解
  • 操作系统实验3 存储管理

    千次阅读 2019-11-25 22:41:00
    理解操作系统存储管理原理 操作系统的发展使得系统完成了大部分的内存管理工作。对于程序员而言,这些内存管理的过程完全透明不可见。因此,程序员开发时从不关心系统如何为自己分配内存,而且永远认为系统可以分配...

    实验目的

    理解操作系统存储管理原理

    操作系统的发展使得系统完成了大部分的内存管理工作。对于程序员而言,这些内存管理的过程完全透明不可见。因此,程序员开发时从不关心系统如何为自己分配内存,而且永远认为系统可以分配给程序所需要的内存。在程序开发时,程序员真正需要做的就是:申请内存、使用内存、释放内存,其他一概无需过问。

    程序1

    申请内存、使用内存以及释放一块内存

    //B17040417.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <malloc.h>
    int main(void)
    {
    char * str;
    if ((str=(char*)malloc(10))==NULL)
    {
      printf("not enough memory to allocate buffer\\n");
      exit(1);
    }
    strcpy(str,"hello");
    printf("string is %s\n",str);
    free(str);
    return 0;
    }
    

    程序2

    在打开文件后,通过fstat()获得文件长度,然后通过malloc()系统调用申请响应大小的内存空间,通过read()将文件内容完全读入该内存空间,并显示出来。

    //yanglonglong.c(路径: /opt/yanglonglong.c)
    #include <stdio.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <string.h>
    #include <sys/types.h>
    #include <fcntl.h>
    main()
    {
      int fd,len;
      void *tp;//void *则为“无类型指针”,可以指向任何数据类型
      struct stat ps;
      fd=open("/opt/yanglonglong.c",0);
      fstat(fd,&ps);
      len=ps.st_size;
      tp=malloc(len);
      read(fd,tp,len);
      printf("%s\n",tp);
      printf("size:%d bytes\n",len);
      close(fd);
    }
    

    知识点

    相关函数
    1)内存动态分配函数

    #include <malloc.h>

    void *malloc(size_t size)

    该函数分配指定大小size个字节的内存空间,成功时返回分配内存的指针(即所分配内存的地址)。该内存区域没有清空。

    2) void free(void * addr);

    该函数释放由malloc()分配的内存,addr是要释放内存空间的起始地址,并且addr必须是被以前malloc( )调用返回的。

    malloc的使用方法及注意事项

    使用C语言进行开发的时候,内存管理非常重要,如果内存管理不当,会导致内存泄露,程序无故死机,
    在C语言中内存管理中,需要使用malloc()和free()两个函数

    1 为什么要使用malloc和free ?

    使用malloc,free可以动态的分配内存和动态释放内存,节约应用程序的运行时,所占用的内存空间,以上也是malloc的优点。

    2 malloc和指针的关系?

    void p= *malloc(long num):该函数分配了num个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
    关于分配失败的原因,应该有多种,比如说空间不足就是一种。
    void free§: 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让这块内存重新交给操作系统管理。
    综上所述:因为malloc分配成功后返回内存的首地址,在使用中是按地址来进行调用,所以有malloc分配内存的时候,就有指针存在。

    3 一般什么情况下需要用到malloc ?

    在程序运行的时候,可变的array,struct可以用到malloc分配内存,也可以采用分配一个连续的空间 存储一批相同类型的变量。

    4 malloc的用法

    程序代码:

    char *p = NULL;
    p= (char *)malloc(100 * sizeof(char)); //分配100个字符串
    if (NULL == p) //检测malloc是否分配成功
    {
    exit (1);
    }
    //使用分配空间
    free(p); //释放空间
    p= NULL; //指针释放
    
    5 malloc使用注意事项
    1. malloc内存空间后,需要检查是否分配成功!
    2. 使用完毕后需要释放内存空间,释放后应该把指向这块内存的指针指向NULL,避免再次使用时,出现奇怪的错误现象。
    3. malloc内存后,不释放会产生内存泄露,多次使用free释放会导致程序报错。
    4. malloc内存时候,需要对返回的指针类型做强制转换。
    read函数

    用read函数读取数组中的元素:

    char buf[200];
    read(0, buf, 5);
    

    第一个参数说明的是从0开始读取
    第二个参数是:要读取的数组buf
    第三个参数是:要读5个

    总结:从第0个开始读取buf中的5个元素(连续的)

    fstat

    功能:
    获得文件或共享内存区的信息
    头文件:

    #include <sys/stat.h> 
    #include <unistd.h> 
    #include <fcntk.h> 
    

    函数原形:

    int stat(const char *file_name,struct stat *buf);
    

    参数:
    file_name 文件名
    buf stat结构
    返回值:
    成功返回0,出错返回-1
    对于普通文件stat结构可以获得12个以上的成员信息,然而当fd指代一个共享内存区对象时,只有四个成员含有信息。

    struct stat{
    	mode_t st_mode;
    	uid_t st_uid;
    	gid_t st_gid;
    	off_t st_size;
    };
    
    exit()函数:

    所在头文件:stdlib.h
    功 能: 关闭所有文件,终止正在执行的进程。
    exit(1)表示异常退出.这个1是返回给操作系统的。
    exit(x)(x不为0)都表示异常退出
    exit(0)表示正常退出
    exit()的参数会被传递给一些操作系统,包括UNIX,Linux,和MS DOS,以供其他程序使用。
    stdlib.h: void exit(int status);
    参 数 : status //程序退出的返回值.

    exit函数和return函数的主要区别:

    1)exit用于在程序运行的过程中随时结束程序,exit的参数是返回给OS的。main函数结束时也会隐式地调用exit函数。exit函数运行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同时刷新所有输出流、关闭所有打开的流并且关闭通过标准I/O函数tmpfile()创建的临时文件。exit是结束一个进程,它将删除进程使用的内存空间,同时把错误信息返回父进程,而return是返回函数值并退出函数。通常情况:

    • exit(0)表示程序正常,

    • exit(1)和exit(-1)表示程序异常退出,exit(2)表示表示系统找不到指定的文件。

    在整个程序中,只要调用exit就结束(当前进程或者在main时候为整个程序)。

    2)return是语言级别的,它表示了调用堆栈的返回;return( )是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。在多个进程时。如果有时要检测上个进程是否正常退出。就要用到上个进程的返回值,依次类推。而exit是系统调用级别的,它表示了一个进程的结束。

    3)exit函数是退出应用程序,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息。

    4)和机器和操作系统有关的一般是: 0为正常退出,非0为非正常退出;

    进程环境与进程控制

    ​ exit(int n)其实就是直接退出程序,因为默认的标准程序入口为 int main(int argc, char** argv),返回值是int型的。一般在shell下面,运行一个程序,然后使用命令echo $?就能得到该程序的返回值,也就是退出值,在main()里面,你可以用return n,也能够直接用exit(n)来做。unix默认的正确退出是返回0,错误返回非0。

    理论上exit可以返回小于256的任何整数。返回的不同数值主要是给调用者作不同处理的。

    单独的进程是返回给操作系统的。如果是多进程,是返回给父进程的。父进程里面调用waitpid()等函数得到子进程退出的状态,以便作不同处理。根据相应的返回值来让调用者作出相应的处理.总的说来,exit()就是当前进程把控制权返回给调用该程序的程序,括号里的是返回值,告诉调用程序该程序的运行状态。

    1) 进程的开始:

    C程序是从main函数开始执行, 原型如下:int main(int argc, char *argv[]);通常main的返回值是int型, 正确返回0。如果main的返回值为void, 某些编译器会给出警告, 此时main的返回值通常是0。

    2)进程终止:

    C程序的终止分为两种: 正常终止和异常终止。正常终止分为: return, exit, _exit, _Exit, pthreade_exit。异常中指分为: abort, SIGNAL, 线程响应取消。
    主要说一下正常终止的前4种, 即exit系列函数.

    #include <stdlib.h>   
    void exit(int status);
    void _Exit(int status);
    
    #include <unistd.h>   
    void _exit(int status);
    

    以上3个函数的区别是:exit()(或return 0)会调用终止处理程序和用户空间的标准I/O清理程序(如fclose), exit和 Exit不调用而直接由内核接管进行清理。因此, 在main函数中exit(0)等价于return 0.

    3) atexit终止处理程序:

    ISO C规定, 一个进程最多可登记32个终止处理函数, 这些函数由exit按登记相反的顺序自动调用。如果同一函数登记多次, 也会被调用多次。
    原型如下:

    #include <stdlib.h>
    
    int atexit(void (*func)(void));
    

    其中参数是一个函数指针, 指向终止处理函数, 该函数无参无返回值。atexit函数本身成功调用后返回0。

    以下面的程序为例:

    #include <stdlib.h>
    
    static void myexit1()
    {
        printf("first exit handler\n");
    }
    
     
    static void myexit2()
    {
        printf("second exit handler\n");
    }
     
    
    int main()
    {
        atexit(my_exit2)atexit(my_exit1)atexit(my_exit1)printf("main is done\n");
    return 0;
    }
    

    运行结果:

    $ ./a.out
    main is done
    first exit handler
    first exit handler
    second exit handler
    

    注意上面的结果,可以发现这些函数由exit按登记相反的顺序自动调用(先myexit1后myexit2)。如果同一函数登记多次, 也会被调用多次(如这里的myexit1)。而这些处理函数都是在程序退出的时候利用atexit函数调用了这些处理函数。但是如果用_exit()退出程序,则它不关闭任何文件,不清除任何缓冲器、也不调用任何终止函数!

    展开全文
  • 操作系统实验报告 -- 存储管理,使用FIFO算法,本身不难。希望大家能用上
  • 兰州大学操作系统实验存储管理模拟题目和答案
  • 用C语言来模拟操作系统存储管理,主要包括:分页存储管理,分段存储管理,段页式存储管理.
  • 过简单的程序模拟两种存储管理算法,通过输入页面访问序列,查页表等操作判别是否缺页,按照FIFO和LRU两种算法淘汰页面,并调入所访问的页面,打印输入结果,在程序中,0代表为空,*代表缺页。 向管道中写入各自的...
  • 操作系统虚拟存储管理实验

    千次阅读 2019-06-01 17:02:22
    操作系统虚拟存储管理实验 开辟一块内存空间,作为模拟内存(malloc) 空间大小为2^14字节 假设系统的页面大小为256字节,每个页表项占4个字节(系统的物理页面数为2^6,每个页表正好占一个页面) 用位图刻画内存页面的...

    操作系统虚拟存储管理实验

    • 开辟一块内存空间,作为模拟内存(malloc) 空间大小为2^14字节
    • 假设系统的页面大小为256字节,每个页表项占4个字节(系统的物理页面数为2^6,每个页表正好占一个页面)
    • 用位图刻画内存页面的分配状态,可以用一个辅助的变量来对空闲内存页面计数
      每个进程的虚拟地址空间也是2^14字节
    • 每个进程分配9个页面(连页表一共10个页面)
    • 创建12个作业,并模拟作业的运行
      - 创建12个文件,模拟磁盘上的代码和数据
      - 可以在文件的第i*256字节处写入<作业号,页面号>,以识别相应的页面

    作业的模拟运行过程

    作业的模拟运行过程
    用VMware虚拟机进行实验
    在这里插入图片描述
    有需要联系QQ:2558957494

    展开全文
  • 操作系统存储管理实验报告

    千次阅读 2020-01-20 09:47:42
    课程名称 计算机操作系统 实验名称 存储管理实验 实验类型 验证 设计 综合 创新 【实验目的】 实验目的: 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚 拟存储请求页式...

    华中农业大学 学生实验报告

    课程名称 计算机操作系统 实验名称 存储管理实验 实验类型 验证 设计
    综合 创新
    【实验目的】
    实验目的:

    1. 通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点,掌握虚 拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
      实验要求:掌握五种存储管理算法
      1)最佳淘汰算法(OPT)
      2)先进先出的算法(FIFO)
      3)最近最久未使用算法(LRU)
      4)最不经常使用算法(LFU)
      5)最近未使用算法(NUR)
    2. 熟悉内存自由空闲队列的分配策略及熟悉内存分区的回收原则及实现过程
      【实验内容】
      设计一个虚拟存储区和内存工作区,并使用下述算法计算访问命中率。
      1)最佳淘汰算法(OPT)
      2)先进先出的算法(FIFO)
      3)最近最久未使用算法(LRU)
      4)最不经常使用算法(LFU)
      5)最近未使用算法(NUR)
      命中率=1-页面失效次数/页地址流长度
      模拟内存的动态分配和回收,并编程实现。
      【实验环境】(含主要设计设备、器材、软件等)
      Pc电脑一台

    【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)
    实验步骤:

    程序说明及实现:
    1.
    先进先出算法:原理是优先淘汰最早进入内存的页面,FIFO 算法是最简单的页面置换算法。FIFO 页面置换算法为每个页面记录了调到内存的时间,即必须置换页面时会选择最旧的页面。“FIFO 算法当进程分配到的页面数增加时,缺页中断的次数可能增加也可能减少”。 FIFO 算法基于队列实现,不是堆栈类算法。注意,并不需要记录调入页面的确切时间,可以创建一个 FIFO 队列,来管理所有的内存页面。置换的是队列的首个页面。当需要调入页面到内存时,就将它加到队列的尾部。FIFO 页面置换算法易于理解和编程。然而,它的性能并不总是十分理想:其一,所置换的页面可以是很久以前使用过但现已不再使用的初始化模块。其二,所置换的页面可以包含一个被大量使用的变量,它早就初始化了,但仍在不断使用。
    2.
    最近最久未被使用算法:即淘汰最近没有使用的页面,选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
    3.
    最近未使用算法:当某一页首次装入主存时,该帧的使用位设置为1;当该页随后再被访问到时,它的使用位也被置为1。对于页替换算法,用于替换的候选帧集合看做一个循环缓冲区,并且有一个指针与之相关联。当某一页被替换时,该指针被设置成指向缓冲区中的下一帧。当需要替换一页时,操作系统扫描缓冲区,以查找使用位被置为0的一帧。每当遇到一个使用位为1的帧时,操作系统就将该位重新置为0;如果在这个过程开始时,缓冲区中所有帧的使用位均为0,则选择遇到的第一个帧替换;如果所有帧的使用位均为1,则指针在缓冲区中完整地循环一周,把所有使用位都置为0,并且停留在最初的位置上,替换该帧中的页。由于该算法循环地检查各页面的情况,故称为 CLOCK 算法,又称为最近未用( Not Recently Used, NRU )算法。
    4.
    最佳置换算法:当要调入一页而必须淘汰旧页时,应该淘汰以后不再访问的页,或距最长时间后要访问的页面。它所产生的缺页数最少,然而,却需要预测程序的页面引用串,这是无法预知的,不可能对程序的运行过程做出精确的断言,不过此理论算法可用作衡量各种具体算法的标准。
    5.最不经常使用置换算法:最不经常使用(LFU)页面置换算法要求置换具有最小计数的页面。这种选择的原因是,积极使用的页面应当具有大的引用计数。然而,当一个页面在进程的初始阶段大量使用但是随后不再使用时,会出现问题。由于被大量使用,它有一个大的计数,即使不再需要却仍保留在内存中。一种解决方案是,定期地将计数右移 1 位,以形成指数衰减的平均使用计数。

    FF首次适应算法(First Fit):该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。特点: 该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。
    最佳适应算法(Best Fit):该算法总是把既能满足要求,又是最小的空闲分区分配给作业。为了加速查找,该算法要求将所有的空闲区按其大小排序后,以递增顺序形成一个空白链。这样每次找到的第一个满足要求的空闲区,必然是最优的。
    最坏适应算法(Worst Fit):最坏适应算法是将输入的作业放置到主存中与它所需大小差距最大的空闲区中。空闲区大小由大到小排序。
    说明:
    本实验的程序设计基本上按照实验内容进行。即首先用 srand( )和 rand( )函数定义和产生指 令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
    (1)通过随机数产生一个指令序列,共 320 条指令。指令的地址按下述原则生成:
    A:50%的指令是顺序执行的
    B:25%的指令是均匀分布在前地址部分
    C:25%的指令是均匀分布在后地址部分
    (2)将指令序列变换为页地址流
    设:页面大小为 1K; 用户内存容量 4 页到 32 页; 用户虚存容量为 32K。
    代码截图:
    初始化代码

    结果截图:

    Excel 绘制图像;

    FF,BF,WF代码截图:

    实验结果截图:

    【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)

    1. 对代码的理解:FIFO算法是最新进入的页面在尾部,最久进入的在头部,每当发生缺页中断时,就替换掉表头的页面并把新调入的页面加入到链表的末尾(通过改变 busypf_head和 busypf_tail 和 freepf_head实现);LRU 算法是通过比较已经调入内存的页面的时间;选出最早调度内存的算法。(比较time);NUR算法是将页面被访问设置R位,页面被写入M位,比较四种形况,选择出一个情况最容易的进行置换;OPT 算法需要比较已经进入内存的页面哪些最久不会被使用,并将其换出,这是一个理想算法且命中率比较高;最不经常使用的置换算法:算法根据数据的历史访问频率来淘汰数据(比较counter).
    2. 五个算法比较:通过excel表格画图可以看出:显然OPT算法的命中率更高;其他四种算法的命中率较为相似,但从别的参考资料可以看到LRU,NUR 的命中率比其他两个略高。
    3. 首次适应算法(First Fit)特点: 该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。缺点:低地址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低地址部分开始,会增加查找的开销。
      最佳适应算法(Best Fit):孤立地看,该算法似乎是最优的,但事实上并不一定。因为每次分配后剩余的空间一定是最小的,在存储器中将留下许多难以利用的小空闲区。同时每次分配后必须重新排序,这也带来了一定的开销。特点:每次分配给文件的都是最合适该文件大小的分区。缺点:内存中留下许多难以利用的小的空闲区。
      最坏适应算法(Worst Fit)特点:尽可能地利用存储器中大的空闲区。缺点:绝大多数时候都会造成资源的严重浪费甚至是完全无法实现分配。
    4. 通过上述三种适应的算法各有优缺点,在具体的情境中要找到具体的适应算法。
    5. 通过这次的学习懂得了五种页面置换的算法,并作图;有些遗憾的是并没有看到FIFO的抖动现象。懂得了三种动态分区算法,并能够理解各个算法的优缺点。这次的学习过程收获很大。
    展开全文
  • 实现了 对操作系统中的存储管理进行了模拟 使用的算法有先进先出 和最近最少使用算法
  • 输入进程数,创建随机进程,按照从0开始的时间量,根据到达时刻和所需空间,计算工作分区表和空闲分区表,直到所有进程完成为止。
  • 教育资料 教育资料 操作系统实验报告 实验序号 7 实验项目名称 Linux 存储管理操作实践 学号 姓名 专业班 实验地点 指导教师 实验时间 一实验目的及要求 通过本实验的学习使学生掌握 Linux 存储管理相关操作的基本...
  • 操作系统实验报告 实验序号 7 实验项目名称 Linux 存储管理操作实践 学 号 姓 名 专业班 实验地点 指导教师 实验时间 一实验目的及要求 通过本实验的学习使学生掌握 Linux 存储管理相关操作的基本方法 以学生自主...
  • 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。...本实验的目的是通过请求页式存储管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。
  • 教育资料 操作系统实验报告 实验序号7 实验项目名称Linux存储管理操作实践 学 号 姓 名 专业班 实验地点 指导教师 实验时间 一实验目的及要求 通过本实验的学习使学生掌握Linux存储管理相关操作的基本方法 以学生...
  • 大学计算专业,操作系统实验报告,存储管理
  • 操作系统 存储管理实验报告

    千次阅读 多人点赞 2020-06-19 10:05:40
    实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 二、实验内容 (1) 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对...
  • 三、实验内容 (1) 通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成: 1. 50%的指令是顺序执行的; 2. 25%的指令是均匀分布在前地址部分; 3. 25%的指令是均匀分布在后地址部分; 具体的实施...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,010
精华内容 404
关键字:

操作系统实验存储管理