实验五 操作系统之存储管理
2015-06-25 08:55
281 查看
网络工程专业 姓名:蔡利聪 学号:201306114117
一、目的和要求
1. 实验目的
连续内存分配方式会形成许多“碎片”,虽然可以通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。如果允许将一个进程直接分散地装入到许多不相邻接的分区中,则无需再进行“紧凑”。基于这一思想而产生了离散分配方式。
如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面兑换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入内存后方能运行。
本实验通过程序模拟操作系统的基本分页存储管理方式,进一步理解这一内存分配方式的原理和特点,加深对理论知识的掌握。
2.实验要求
(1)用C语言或Java语言编写程序模拟操作系统对内存的基本分页存储管理方式。
(2)程序要能正确对“内存”进行“分配”和“回收”,能接受用户的输入,显示内存的分配情况,并有一定的容错能力。
二、实验内容
本实验假定内存空间已经按块划分,目标程序无需关心内存块大小等底层细节,只需按算法对内存块进行分配即可。程序应该实现以下功能:
1、内存初始化。假定内存块共有N个,初始化后的内存空间应该有一部分已经被使用,这可以用随机数或程序内部的其他算法完成。
2、程序应该能接受用户输入的进程信息,并为之分配内存,返回分配结果(成功或失败),注意,此处应该考虑到不合法的输入并进行相应处理。
3、程序能回收用户指定的进程所占用的内存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。
4、能直观合理地显示内存分配情况。
5、程序界面友好,便于操作和查看运行结果。
三、实验方法、步骤及结果测试
1. 源程序名:存储管理.cpp
可执行程序名:存储管理.exe
2. 原理分析
(1)编写该程序首先要定义一个一定空间大小的内存块100,即申请空闲区空间最大值,并且要初始化内存状态标志数组block[i],以及初始化存放进程的数组process[i][j],保证内存大小足够分配给相应的进程使用。
(2)通过设置菜单项,达到友好的访问内存的请求界面,把创建进程向内存获取空间,把结束进程让内存回收空间分为两个程序段函数,各自独立完成相应的功能,最后通过主函数直接调用创建进程和结束进程这两个函数。
3. 主要程序段及其解释:
4. 运行结果
默认创建的内存为100块,其中系统占用18块,剩余82块可供创建进程使用,当创建进程号为1,页面数为3的进程后,内存立刻为进程分配了3块空间0,1,2;当进程结束时,内存回收进程号1的空间,本次实验结果符合预期。
四、实验总结
本次实验是有关存储管理空间分配的算法的实现,实验内容相对之前的进程调度稍微简洁些,只需要通过内存空间大小,定义数组页表,然后进程请求空间块或释放空间块只需通过数组页表进行访问,然后内存提供相应的内存分配和回收。
虽然步骤比较清晰,对于二维数组使用的知识存在欠缺,写相关的代码比较不熟练,中间遇到很多困难,比如二维数组的调度,还有一些基本的C语言的语法结构掌握不熟练,而且对算法与与程序之间的思维不清晰,导致在写程序中出现较多问题,然后通过查找课本,上网搜寻资料,询问同学进行帮助解答,最后得到基本的实验程序。
一、目的和要求
1. 实验目的
连续内存分配方式会形成许多“碎片”,虽然可以通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。如果允许将一个进程直接分散地装入到许多不相邻接的分区中,则无需再进行“紧凑”。基于这一思想而产生了离散分配方式。
如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面兑换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入内存后方能运行。
本实验通过程序模拟操作系统的基本分页存储管理方式,进一步理解这一内存分配方式的原理和特点,加深对理论知识的掌握。
2.实验要求
(1)用C语言或Java语言编写程序模拟操作系统对内存的基本分页存储管理方式。
(2)程序要能正确对“内存”进行“分配”和“回收”,能接受用户的输入,显示内存的分配情况,并有一定的容错能力。
二、实验内容
本实验假定内存空间已经按块划分,目标程序无需关心内存块大小等底层细节,只需按算法对内存块进行分配即可。程序应该实现以下功能:
1、内存初始化。假定内存块共有N个,初始化后的内存空间应该有一部分已经被使用,这可以用随机数或程序内部的其他算法完成。
2、程序应该能接受用户输入的进程信息,并为之分配内存,返回分配结果(成功或失败),注意,此处应该考虑到不合法的输入并进行相应处理。
3、程序能回收用户指定的进程所占用的内存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。
4、能直观合理地显示内存分配情况。
5、程序界面友好,便于操作和查看运行结果。
三、实验方法、步骤及结果测试
1. 源程序名:存储管理.cpp
可执行程序名:存储管理.exe
2. 原理分析
(1)编写该程序首先要定义一个一定空间大小的内存块100,即申请空闲区空间最大值,并且要初始化内存状态标志数组block[i],以及初始化存放进程的数组process[i][j],保证内存大小足够分配给相应的进程使用。
(2)通过设置菜单项,达到友好的访问内存的请求界面,把创建进程向内存获取空间,把结束进程让内存回收空间分为两个程序段函数,各自独立完成相应的功能,最后通过主函数直接调用创建进程和结束进程这两个函数。
3. 主要程序段及其解释:
#include <stdio.h> #include <windows.h> #define N 100 // 共有100个内存块 int process [N+1]; // 存放每个进程的页表 int block ; // 内存块状态标志数组,0:空闲,1:使用 int blockCount; // 记录当前内存剩余空间 int processCount; // 记录当前进程数 bool flag = true; void init(); void output(); bool createProcess(); bool endProcess(); void menu(); //主函数 void main() { init(); menu(); } void init() { int i, j; for (i=0; i<N; i++)// 初始化内存状态标志数组 block[i] = 0; for (i=0; i<20; i++) block[rand()%(N-1)] = 1; blockCount = 0; for (i=0; i<N; i++) if (block[i] == 0) blockCount++; // 初始化存放进程的数组 for (i=0; i<N; i++) { process[i][0] = 0; for (j=1; j<N; j++) process[i][j] = -1; } processCount = 0; printf("初始化结果如下:"); output(); flag = false; } void output() { printf("\n内存总量:%d 块, 已用空间:%d 块, 剩余空间:%d 块, 进程总数:%d 个\n", N, N-blockCount, blockCount, processCount); if (flag && blockCount < N) { printf("已使用的内存块(%d):\n", N-blockCount); for (int k=0,count=0; k<N; k++) { if (block[k] == 1) printf("%2d ", k, ++count); if (count == 15) { putchar('\n'); count = 0; } } putchar('\n'); } // 输出各进程占用内存详细情况 if(processCount>0) { printf("内存详细使用情况如下:\n"); for (int i=0; i<N; i++) { if (process[i][0] > 0) { printf("进程号:%d \n占用内存块(%2d):", i, process[i][0]); for (int j=1,count=0; j<=process[i][0]; j++) { printf("%2d ", process[i][j], count++); if (count == 15) { putchar('\n'); printf(" "); count = 0; } } putchar('\n'); } } } else printf("当前内存无进程!\n"); // 输出空闲内存块 putchar('\n'); } bool createProcess() { int pid, pages, k = 0; loop:printf("请输入进程号(小于%d)和所需页面数:", N); scanf("%d%d", &pid, &pages); if (pid > 99) { printf("错误!进程号过大!\n"); goto loop; } if (pages > blockCount) return false; blockCount -= pages; process[pid][0] = pages; for (int i=1; i<=pages; i++) { while (block[k]==1 && k<100) k++; process[pid][i] = k; block[k] = 1; k++; } processCount++; return true; } bool endProcess() { int pid, pages; if (processCount < 1) { printf("当前内存没有进程!\n\n"); return false; } printf("当前内存中的进程有 %d 个, 进程号为:", processCount); for (int i=0; i<N; i++) if (process[i][0] > 0) printf("%2d ", i); putchar('\n'); printf("请输入您要结束的进程号(小于%d):", N); scanf("%d", &pid); pages = process[pid][0]; if (pages == 0) { printf("对不起!该进程不存在!\n"); return false; } for (int j=1; j<pages; j++) { block[process[pid][j]] = 0; process[pid][j] = -1; } process[pid][0] = 0; processCount--; blockCount += pages; return true; } void menu() { int choice; while (true) { printf("操作菜单:\n"); printf(" 1 --> 创建进程\n 2 --> 结束进程\n 3 --> 查看内存\n 0 --> 退出程序\n"); printf("请输入您要进行的操作:"); scanf("%d", &choice); switch (choice) { case 1: if (createProcess()) printf("创建新进程成功!\n\n"); else printf("抱歉!内存空间不足,创建新进程失败!\n\n"); break; case 2: if (endProcess()) printf("进程已结束!\n\n"); else printf("进程结束失败!\n\n"); break; case 3: output(); break; case 0: return ; default: printf("对不起!您的选择有误!请重新选择!\n\n"); } } }
4. 运行结果
默认创建的内存为100块,其中系统占用18块,剩余82块可供创建进程使用,当创建进程号为1,页面数为3的进程后,内存立刻为进程分配了3块空间0,1,2;当进程结束时,内存回收进程号1的空间,本次实验结果符合预期。
四、实验总结
本次实验是有关存储管理空间分配的算法的实现,实验内容相对之前的进程调度稍微简洁些,只需要通过内存空间大小,定义数组页表,然后进程请求空间块或释放空间块只需通过数组页表进行访问,然后内存提供相应的内存分配和回收。
虽然步骤比较清晰,对于二维数组使用的知识存在欠缺,写相关的代码比较不熟练,中间遇到很多困难,比如二维数组的调度,还有一些基本的C语言的语法结构掌握不熟练,而且对算法与与程序之间的思维不清晰,导致在写程序中出现较多问题,然后通过查找课本,上网搜寻资料,询问同学进行帮助解答,最后得到基本的实验程序。
相关文章推荐
- Qt常用快捷键
- 数据库(表)的逻辑备份与恢复
- android 使用git打补丁
- php中session的生命周期
- SWT Table示例
- 实验五存储管理实验
- MySQL的ERROR 1366 (HY000): Incorrect string value错误解决
- 黑马程序员——高新技术--泛型
- 14款优秀的代码展示网站
- PHP Session可能会引起并发问题
- 设计师不应该错过的响应式设计框架
- iOS 9适配系列教程:后台定位
- 自举驱动、top开关电源、光耦拾遗
- python 去除 list 重复元素
- JSON编码格式提交表单数据详解
- javascript客户端检测技术
- 卡尔曼滤波的原理说明
- 召回率
- windows调试子系统
- CentOS开机自动运行程序的脚本