资源描述
. .
操
作
系
统
实
验
报
告
XX:卢一一
学号:9
学校:清华大学
专业:计算机科学与技术
班级:2021级—2班
根本分页存储管理
实验目的
连续存分配方式会形成许多“碎片〞,虽然可以通过“紧凑〞方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。如果允许将一个进程直接分散地装入到许多不相邻接的分区中,那么无需再进展“紧凑〞。基于这一思想而产生了离散分配方式。如果离散分配的根本单位是页,那么称为分页存储管理方式;如果离散分配的根本单位是段,那么称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面兑换功能,那么称为根本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入存前方能运行。
本实验通过程序模拟操作系统的根本分页存储管理方式,进一步理解这一存分配方式的原理和特点,加深对理论知识的掌握。
实验要求
1、用C语言或Java语言编写程序模拟操作系统对存的根本分页存储管理方式
2、程序要能正确对“存〞进展“分配〞和“回收〞,能承受用户的输入,显示存的分配情况,并有一定的容错能力。
3、每个人独立按时完成实验容。
实验容
本实验假定存空间已经按块划分,目标程序无需关心存块大小等底层细节,只需按算法对存块进展分配即可。程序应该实现以下功能:
1、存初始化。假定存块共有N个,初始化后的存空间应该有一局部已经被使用,这可以用随机数或程序部的其他算法完成。
2、程序应该能承受用户输入的进程信息,并为之分配存,返回分配结果〔成功或失败〕,注意,此处应该考虑到不合法的输入并进展相应处理。
3、程序能回收用户指定的进程所占用的存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。
4、能直观合理地显示存分配情况。
5、程序界面友好,便于操作和查看运行结果。
实验结果
实验总结
根本分页的思想是比较简单的,而且实验前教师已经给出了一种可行的数据构造来存储程序中需要用到的数据,因此这个实验在构思上是没有多少难度的。由于程序中主要使用的是数组,操作起来比较方便,不像前两个实验需要用到大量的链表操作。在这次试验中,我主要遇到了以下一些问题:
1、程序刚写完时,记录“存〞中的进程数的变量和当前剩余总存的变量的值不正确,经检查后发现是在完毕进程时没有同时更新这些数据。
2、存使用情况应该以哪种形式输出以及输出哪些信息。最终我选择了尽可能详细地输出有用信息,通过空格、空行、对齐等手段尽力使输出格式简洁美观。比方,在输出每个进程的存使用情况时,首先输出该进程占用的总存,然后以统一的对齐方式依次输出各个存块编号。
当然,对于不同的模块输出的信息也应该不一样,比方,存初始化完毕后应该输出哪个存块被占用了,否那么无法判断后续的存分配是否正确,但在以后查看存使用情况时那么不必把所有已占用的存块输出,因为每个进程都会单独把自己占用的存块显示出来。为了到达这种效果,我使用了一个全局变量作为判断依据,详细情况见附录中代码。
3、程序的容错性。这是一个容易被忽略的问题。这个程序起初根本没考虑这个问题,但在后来的调试过程中,逐渐加上了一些根本的容错功能,比方用户在完毕某进程时,其输入的进程号可能根本不存在,这时应该给出用户出错提示,并要求用户重新输入,但这里用了一个编程中不太推荐的方式:goto 语句。
总体而言,这次实验还是比较顺利的,没有遇到什么特别难解决的问题。通过自己编程模拟存分配,我不仅加深了对这种存管理方式的理解,也增强了C语言的编程能力。通过这几次的实验,我感觉手工写一个几百行的程序不像以前那么困难了。
附录
#include <stdio.h>
#include <windows.h>
#define N 100 // 共有100个存块
int process[N][N+1]; // 存放每个进程的页表
int block[N]; // 存块状态标志数组,0:空闲,1:使用
int blockCount; // 记录当前存剩余空间
int processCount; // 记录当前进程数
bool flag = true;
void init();
void output();
bool createProcess();
bool endProcess();
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");
/*// 输出空闲存块
if (blockCount > 0)
{
printf("空闲存块(%d):\n", blockCount);
for (int k=0,count=0; k<N; k++)
{
if (block[k] == 0)
printf("%2d ", k, ++count);
if (count == 15)
{
putchar('\n');
count = 0;
}
}
putchar('\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");
}
}
}
void main()
{
init();
menu();
}
教育之通病是教用脑的人不用手,不教用手的人用脑,所以一无所能。教育革命的对策是手脑联盟,结果是手与脑的力量都可以大到不可思议。
. .word.zl.
展开阅读全文