操作系统B实验报告华北电力大学科技学院.docx
《操作系统B实验报告华北电力大学科技学院.docx》由会员分享,可在线阅读,更多相关《操作系统B实验报告华北电力大学科技学院.docx(32页珍藏版)》请在冰豆网上搜索。
操作系统B实验报告华北电力大学科技学院
课程设计报告
(2011--2012年度第1学期)
名称:
操作系统原理课程设计B
院系:
信息工程系
班级:
软件09k2
学号:
091909020227
学生姓名:
闫雪峰
指导教师:
郭丰娟张琦
设计周数:
1
成绩:
日期:
2011年11月25日
《操作系统原理课程设计B》课程设计
任务书
一、目的与要求
1.理解和掌握操作系统的基本概念、基本组成与工作原理;
2.理解和掌握操作系统中主要功能模块的工作原理及其实现算法;
3.掌握软件模块设计技能;熟悉并能较好地利用软件开发环境独立编程、调试和分
析程序运行情况,逐渐形成创新思维和从事系统软件的研究和开发能力。
二、主要内容
采用某种程序设计语言,设计与开发一个仿真操作系统,要求具备进程调度、存储器管理、文件及设备管理等基本功能,具体内容包括:
1.模拟单处理器系统的进程调度,加深对进程的概念及进程调度算法的理解;
2.编写一个多线程程序,加深对现代操作系统中线程的理解;
3.编写和调试一个银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法;
4.用可变分区算法模拟主存的分配和回收,加深对存储器管理的理解,熟悉各种主存分配方法;
5.模拟虚拟存储管理中缺页中断及页面置换算法,加深对虚拟存储器管理的理解,熟悉各种页面淘汰算法;模拟设备的分配与回收,加深对设备管理的理解;模拟文件管理的工作过程,从而对各种文件操作命令的实质内容和执行过程有比较深入的了解;模拟磁盘调度的过程,加深对磁盘存储器管理的理解,熟悉各种磁盘调度算法。
6.综合以上实验的结果,并进行集成与设计,开发出一个小型虚拟操作系统。
对以上课程设计内容,将根据学生的专业与实际情况进行调整,某些题目为选作题目。
三、进度计划
序号
设计(实验)内容
完成时间
备注
1
熟悉开发环境及程序设计语言
1天
2
系统的分析、设计
2天
3
调试与集成
1天
4
验收,提交实验报告
1天
四、设计(实验)成果要求
至少完成主要内容中的3项,统一使用课程设计报告书,文字清楚、工整。
五、考核方式
实验结果(60%)+实验报告(30%)+实验过程表现(10%)
学生姓名:
指导教师:
2011年11月25日
一、课程设计(综合实验)的目的与要求
1.理解和掌握操作系统的基本概念、基本组成与工作原理;
2.理解和掌握操作系统中主要功能模块的工作原理及其实现算法;
3.掌握软件模块设计技能;熟悉并能较好地利用软件开发环境独立编程、调试和分
析程序运行情况,逐渐形成创新思维和从事系统软件的研究和开发能力。
二、设计正文
实验1:
单处理器系统的进程调度
1.1实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。
当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。
本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
1.2实验要求
1.设计一个按时间片轮转法实现处理器调度的程序,每个程序由一个PCB表示。
2.程序执行中应能在屏幕上显示出各进程的状态变化,以便于观察调度的整个过程。
1.3实验原理和设计
进程控制块PCB的格式为:
进程名
指针
要求运行时间
已运行时间
状态
指针——进程按顺序排成循环队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程的指针指出第一个进程的进程控制块首地址。
要求运行时间——假设进程需要运行的单位时间数。
已运行时间——假设进程已经运行的单位时间数,初始值为“0”。
状态——有两种状态,“就绪”和“结束”,初始状态都为“就绪”,用0表示。
当一个进程运行结束后,它的状态为“结束”,用1表示。
(1)运行处理器调度程序前,输入进程数并且为每个进程设置所需的服务时间;
(2)把各个进程按顺序排成循环队列,用指针指出队列连接情况;
(3)由于是模拟程序,在时间片轮转的前提下,每次使得相应进程:
执行时间=已执行时间+1;
(4)输出运行细节。
1.4实验结果
实验2:
主存储器空间的分配和回收
2.1实验目的
一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
主存的分配和回收的实现虽与主存储器的管理方式有关的,通过本实验帮助学生理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
2.2实验要求
1.在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。
2.打印空闲区说明表的初始状态,作业4的申请量以及为作业4分配后的空闲区说明表状态;再依次打印作业3和作业2的归还量以及回收作业3,作业2所占主存后的空闲区说明表。
2.3实验原理和设计
1.可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。
随着作业的装入、撤离,主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。
例如:
0
5k
10k
14k
26k
32k
128k
操作系统
作业1
作业3
空闲区
作业2
空闲区
其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
2.4运行结果
实验3:
多线程游戏(贪吃蛇)
3.1实验目的
(1)任何语言,实现多线程游戏,如龟兔赛跑,摇奖机等。
3.2实验原理和设计
(1)vb实现贪吃蛇游戏,用到timer控件实现多线程的控制,实现贪吃蛇的基本功能
(2)连接access数据库,将最高分信息存到数据库。
3.2实验结果
三、课程设计(综合实验)总结
通过本次课程综合实验,我对存储器内部进程调度、空间管理和页面置换等相关算法有了更加深刻的理解,同时锻炼了动手能力,为以后更加深入地学习操作系统这门课程打下了良好的基础。
值得一提的是,本次实验对设计多线程游戏有了些许心得,兴趣所致,今后当加强这方面的学习,开发出一些好玩的小游戏。
计算机相关的学科离不开上机实践,只有通过实践,才能更好地掌握知识,自己以后当主动上机实践相关理论知识。
四、参考文献
[1]《计算机操作系统》,西安电子科技大学出版社,2007年5月第3版;汤小丹梁红兵哲凤屏汤子嬴编著。
[2]游戏开发教程
附录
实验一
//timer.cpp:
定义控制台应用程序的入口点
#include"stdafx.h"
int_tmain(intargc,_TCHAR*argv[])
{
return0;
}
#include
#include
#include
#defineTIME1
typedefstructprocuder
{
intchrName;//进程名字
intintRoundTime;
intintRunningTime;//已经运行时间
charchrFlag;
structprocuder*pointerNext;
}procuder;
intmain()
{
intintTotal;//进程总数
inti;
intintCounter=1;//计数标记
procuder*pNew;//新申请的节点
procuder*pPointer;//当前程序指针
procuder*pPrevious;//当前指针的前一个指针
procuder*pPrint;//输出打印的指针
pPointer=(procuder*)malloc(sizeof(procuder));//初始化指针节点
pPrevious=pPointer;//将俩个指针初始化在一起
printf("请输入总数total:
");
scanf("%d",&intTotal);
for(i=1;i<=intTotal;i++)//初始化各个进程
{
pNew=(procuder*)malloc(sizeof(procuder));//申请新节点
pPrevious->pointerNext=pNew;//将新申请节点与前一个节点连接起来
pPrevious=pNew;//将指示指针移到新申请的指针
printf("请输入第%d进程名字:
",i);
scanf("%d",&(pNew->chrName));
printf("请输入第%d要求运行时间:
",i);
scanf("%d",&(pNew->intRoundTime));
pNew->chrFlag='R';
pNew->intRunningTime=0;//初始化标记为和运行时间
}
pPrevious->pointerNext=pPointer->pointerNext;//设成循环队列
pPointer=pPointer->pointerNext;
while(pPointer->pointerNext!
=pPointer)//运行完剩一个进程结束
{
pPointer->intRunningTime=pPointer->intRunningTime+TIME;//模拟进程运行
//输出当前的状态,代码自己写把
printf("第%d次运行:
当前运行的程序为%d\n",intCounter++,pPointer->chrName);
printf("\n就绪队列情况\n\n进程名字需要时间运行时间状态\n");
if(pPointer->intRunningTimeintRoundTime)//判断当前进程是否完成未完成
{
pPointer=pPointer->pointerNext;//轮转到下一个时间片
pPrevious=pPrevious->pointerNext;//previous后移
}
else{//完成了将当前节点剔除
pPointer->chrFlag='E';//设置标志位
pPrevious->pointerNext=pPointer->pointerNext;//剔除当前节点
pPointer=pPointer->pointerNext;//运行指针后移
}
pPrint=pPrevious;
while(pPrint->pointerNext!
=pPrevious)//输出各个进程的状态
{
printf("%d%d%d%c\n",pPrint->chrName,pPrint->intRoundTime,pPrint->intRunningTime,pPrint->chrFlag);
pPrint=pPrint->pointerNext;//后移
}
printf("%d%d%d%c\n",pPrint->chrName,pPrint->intRoundTime,pPrint->intRunningTime,pPrint->chrFlag);
printf("\n");//换行
}
while(pPointer->intRunningTimeintRoundTime)
{
pPointer->intRunningTime=pPointer->intRunningTime+TIME;//模拟进程运行
printf("第%d次运行:
当前运行的程序为%d\n",intCounter++,pPointer->chrName);
printf("\n就绪队列情况\n\n进程名字需要时间运行时间状态\n");
printf("%d%d%d%c\n\n",pPointer->chrName,pPointer->intRoundTime,pPointer->intRunningTime,pPointer->chrFlag);
}
system("pause");
return0;
}
实验二
//MemoryControl.cpp:
定义控制台应用程序的入口点。
#include"stdafx.h"
int_tmain(intargc,_TCHAR*argv[])
{
return0;
}
#include
#include
#include
typedefstructmemorytable//空间去说明表结构体
{
intintStartAddress;//起始地址
intintLength;//空间长度
intintFlag;//标记为为空表目为未分配
}memorytable;
structprocess//进程的属性包括名字所需时间以运行时间
{
intintName;
intiEndFlag;//标记为标记是否已经卸载过
intiSuccessfullyFitMemory;//是否成功分配内存标记
intintStartTime;
intintNeedTime;
intintRoundTime;
intintNeedMemorySize;
intintStartAddress;
structprocess*sNext;
};
intPrintMemoryTable(structmemorytablesSubMemoryTable[],structprocess*sSubPointer,intintSubTotal)//输出空间说明表的情况
{
inti;
intiCounter=0;//计数器计算总共有多少个自由表项
printf("\n空间说明表:
当前内存分区表总大小为%d个表项\n\n",intSubTotal*2);
printf("栏目地址长度状态\n");
for(i=0;i{
if(sSubMemoryTable[i].intFlag==1)iCounter++;//计数器++有一个自由表项计数器加一
printf("%d%d%d%d\n",i,sSubMemoryTable[i].intStartAddress,sSubMemoryTable[i].intLength,sSubMemoryTable[i].intFlag);
}
printf("当前共有%d个能分配表目,分别从~%d号内存栏目\n",iCounter,iCounter-1);
return0;
}
intCrimple(structmemorytablesSubMemoryTable[],structprocess*sSubPointer,intintSubTotal)//内存缩紧代码
{
inti,j;//计数器
for(i=0;i{
for(j=i+1;j<2*intSubTotal;j++)
{
if(sSubMemoryTable[i].intFlag==1)//如果i不是空表目
{
if((sSubMemoryTable[j].intFlag==1)&&(sSubMemoryTable[i].intStartAddress>sSubMemoryTable[j].intStartAddress))//若j不为空表目且j的开始地址小于i的开始地址,交换
{
sSubMemoryTable[2*intSubTotal]=sSubMemoryTable[i];
sSubMemoryTable[i]=sSubMemoryTable[j];
sSubMemoryTable[j]=sSubMemoryTable[2*intSubTotal];
}
}
else//i为空表目,交换i和j的值
{
if(sSubMemoryTable[j].intFlag==1)//且j不是空表目
{
sSubMemoryTable[2*intSubTotal]=sSubMemoryTable[i];
sSubMemoryTable[i]=sSubMemoryTable[j];
sSubMemoryTable[j]=sSubMemoryTable[2*intSubTotal];
}
}
}
}
//打印输出代码
PrintMemoryTable(sSubMemoryTable,sSubPointer,intSubTotal);
return(0);
}
intFitMemory(structmemorytablesSubMemoryTable[],structprocess*sSubPointer,intintSubTotal)
{
inti=-1;//计数器
while(++i<(2*intSubTotal))//循环找出满足要求的内存块
{
if(sSubMemoryTable[i].intFlag==1)//判断是否表项为未分配
{
if(sSubMemoryTable[i].intLength>sSubPointer->intNeedMemorySize)//判断当前栏的大小是否能放下进程
{
printf("将%d号内存[起始地址%d,内存大小%d]分配给%d进程[占用内存大小%d]\n",i,sSubMemoryTable[i].intStartAddress,sSubMemoryTable[i].intLength,sSubPointer->intName,sSubPointer->intNeedMemorySize);
sSubPointer->intStartAddress=sSubMemoryTable[i].intStartAddress;
sSubMemoryTable[i].intStartAddress=sSubMemoryTable[i].intStartAddress+sSubPointer->intNeedMemorySize;
sSubMemoryTable[i].intLength=sSubMemoryTable[i].intLength-sSubPointer->intNeedMemorySize;
//输出空间说明表
PrintMemoryTable(sSubMemoryTable,sSubPointer,intSubTotal);
return1;
}
if(sSubMemoryTable[i].intLength==sSubPointer->intNeedMemorySize)//刚好相等
{
printf("将%d号内存[起始地址%d,内存大小%d]分配给%d进程[占用内存大小%d]\n",i,sSubMemoryTable[i].intStartAddress,sSubMemoryTable[i].intLength,sSubPointer->intName,sSubPointer->intNeedMemorySize);
sSubPointer->intStartAddress=sSubMemoryTable[i].intStartAddress;
sSubMemoryTable[i].intFlag=0;
sSubMemoryTable[i].intStartAddress=0;
sSubMemoryTable[i].intLength=0;
//缩紧分区说明表,输出空间说明表
Crimple(sSubMemoryTable,sSubPointer,intSubTotal);
return2;
}
}
}
printf("内存分配失败%d号进程:
需要内存空间为%d在内存空闲说明表中无满足要求者\n",sSubPointer->intName,sSubPointer->intNeedMemorySize);//内存分配失败
PrintMemoryTable(sSubMemoryTable,sSubPointer,intSubTotal);
sSubPointer->iSuccessfullyFitMemory=0;//内存分配失败回受时不回收
return0;
}
intRemoveMemory(structmemorytablesSubMemoryTable[],structprocess*sSubPointer,intintSubTotal)//从内存卸载函数
{
inti;//计数器
intj;
intintFlag=0;//标位位
intintStartAddress;
intintLength;//定义起始地址和长度临时变量
intStartAddress=sSubPointer->intStartAddress;
intLength=sSubPointer->intNeedMemorySize;//初始化长度
for(i=intSubTotal*2-1;i>=0;i--)
{
if((sSubMemoryTable[i].intFlag==1)&&(sSubMemoryTable[i].intStartAddress==intStartAddress+intLength))//如果有与归还区下临的空闲分区表
{
printf("有与%d号进程下邻的空闲分区表%d号内存[起始地址%d,长度%d]\n",sSubPointer->intName,i,sSubMemoryTable[i].intStartAddress,sSubMemoryTable[i].intLength);
intLength+=sSubMemoryTable[i].intLength;
intFlag=1;//设置标记位
for(j=i-1;j>=0;j--)//判断是否有与当前表目上临的空闲去
{
if(sSubMemoryTable[j].intFlag=1)//上临的区域不为空表目
{