《操作系统实训》指导书.docx
- 文档编号:3305230
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:35
- 大小:142.85KB
《操作系统实训》指导书.docx
《《操作系统实训》指导书.docx》由会员分享,可在线阅读,更多相关《《操作系统实训》指导书.docx(35页珍藏版)》请在冰豆网上搜索。
《操作系统实训》指导书
《操作系统实训》指导书
一、实训目的
通过操作系统实训,主要强化学生对本课程基础知识的掌握;使学生理论联系实际,加强学生的动手能力;加深对操作系统的基本概念、工作原理和实现方法等理论知识的理解;掌握操作系统各个部分之间的有机联系,从而了解操作系统在整个计算机系统中的地位和作用,巩固和加强与本课程相关的其他计算机课程的知识,提高对计算机专业知识理解的系统性和完整性,并加强合作完成系统的团队精神和提高程序设计的能力。
二、实训内容
本实训的内容为实现一个模拟操作系统。
要求使用实验室所提供的安装有C语言编程环境的计算机,模拟采用多道程序设计方法的单用户操作系统,该操作系统包括进程管理、存储管理、设备管理和文件管理四部分。
三、实训设备
1、PC计算机
2、VC++等软件系统。
四、实训任务及要求
根据实训内容,认真完成模拟操作系统的实现,模拟操作系统需包括进程管理、存储管理、设备管理和文件管理四部分。
实训的基本原理主要包括操作系统中的进程的同步与互斥;常用的进程调度算法;地址重定位;动态页式存储管理技术的页面淘汰算法;设备管理中设备的分配和回收;用死锁避免方法来处理申请独占设备可能造成的死锁;磁盘调度算法等。
本实训结束后,需要学生提交实训的源代码及可执行程序,并提交实训报告。
五、实训基本操作方法
1. 搜集与整理,设定操作系统所面临的操作需求;
2. 设计各部分的实现方案;
3. 程序开发;
4. 程序测试;
5. 系统集成;
6. 提交源程序,完成实训报告。
六、实训项目
任务一 分析操作系统所面临的操作需求
【实训目的】
使学生理解操作系统所面临的操作需求,掌握操作系统中的进程管理、存储管理、设备管理和文件管理等功能。
【实训内容】
1. 分析操作系统所面临的操作需求;
2. 熟悉实训环境;
3. 资料搜集与整理,进行实训的前期准备。
【预习要求】
操作系统的功能及实现的基本原理。
【实训步骤】
1. 分析操作系统所面临的操作需求:
进程管理、存储管理、设备管理和文件管理,进一步熟悉各模块的工作原理;
2. 根据操作需求,进行系统的整体设计,画出系统总体的功能模块图,如下图1所示;
3. 根据上一步得出的功能模块图,进行资料的搜集与整理,并熟悉实训环境,为之后实训任务的完成打下坚实的基础。
图1系统功能模块图
【注意事项】
操作系统中各模块之间的功能划分。
【思考题】
1. 操作系统中各模块有怎样的功能?
2. 它们之间有怎样的联系?
3. 针对某一特定的应用环境,如何完善操作系统的功能?
任务二 进程管理
【实训目的】
掌握临界区的概念及临界区的设计原则;掌握信号量的概念、PV操作的含义以及应用PV操作实现进程的同步与互斥;分析进程争用资源的现象,学习解决进程互斥的方法;掌握进程的状态及状态转换;掌握常用的进程调度算法。
【实训内容】
1.分析进程的同步与互斥现象,编程实现经典的进程同步问题——生产者消费者问题的模拟;
2.编写允许进程并行执行的进程调度程序,在常用的进程(作业)调度算法:
先来先服务算法、短作业优先算法、最高响应比优先算法、高优先权优先算法等调度算法中至少选择三种调度算法进行模拟,并输出平均周转时间和平均带权周转时间。
【预习要求】
进程同步与互斥的概念及实现方法;进程调度的作用及常用的调度算法。
【实训步骤】
1.分析计算机系统中对资源的分配与释放过程:
计算机系统中的每个进程都可以消费或生产某类资源。
当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
2.定义生产者消费者问题中的各数据结构,并初始化信号量;
3.创建生产者与消费者进程,利用信号量实现生产者与消费者之间的同步与互斥;可参考的部分源代码如下:
include"windows.h"
#include"conio.h"
#include"stdio.h"
#defineMAX20 //定义缓冲池的最大容量是20
intcount=5; //初始产品的数量为5
voidProclucer()//生产者函数
{
while
(1)
{
if(count>=MAX)
{
printf("缓冲池已满!
等待1秒!
\n");
Sleep(3000);
}
else
{
count++;
printf("生产了一个产品!
当前产品的总数量是:
%d\n\n",count);
Sleep(1300); //注意毫秒为单位
}
}
}
voidConsumer() //消费者函数
{
while
(1)
{
if(count==0)
{
printf("缓冲池已空!
等待2秒!
\n");
Sleep(2000);
}
else
{
count--;
printf("取出了一个产品!
当前产品的数量是:
%d\n\n",count);
Sleep(2000);
}
}
}
HANDLEahThread;
HANDLEbhThread;
HANDLEhThread;
int tStop() //停止函数
{
intl=getchar();
returnl;
}
voidStart() //开始函数
{ ahThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Proclucer,NULL,0,NULL); bhThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Consumer,NULL,0,NULL); hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)tStop,NULL,0,NULL); //多线程
int IsStop=tStop();
if(IsStop==0) //满足停止条件
{
CloseHandle(ahThread);
CloseHandle(bhThread);
CloseHandle(hThread);
}
}
voidshengcanzexiaofeize() //主函数
{
printf("**********会出现返回不了主界面的情况*********************");
Start(); //开始
printf("\n");
}
4. 运行并测试程序,运行界面如下图2所示:
图2生产者与消费者问题程序模拟效果图
5.分析常用的进程调度算法的工作原理,优先级法可被用作业或进程的调度策略。
以下步骤以优先级法为例说明实训步骤。
图3高优先权算法的工作流程:
首先,系统或用户按某种原则为作业或进程指定一个优先级来表示该作业或进程所享有的调度优先级权。
该算法的核心是确定进程或作业的优先级。
确定优先级的方法分为两类:
静态法和动态法。
静态法根据作业或进程的静态特性,在作业或进程开始执行之前就确定它们的优先级,一旦开始执行之后就不能改变。
动态法则不然,它把作业或进程的静态特性和动态特性结合起来确定作业或进程的优先级,随着作业或进程的执行过程,其优先级不断变化。
本实训指导书以动态法为例进行说明。
静态优先级的调度算法实现虽然简单,系统开销小,但由于静态优先级一旦确定之后,直到执行结束为止始终保持不变,从而系统效率较低,调度性能不高,而动态优先级的系统效率较高,调度性能也高。
6.高优先权算法的设计,下图4所示:
图3高优先权算法的流程
图4高优先权算法的设计
先读入进程,比较进程的优先级,排列出分配CPU的队列,按时间片分配CPU,一个时间片后,优先级减1,再一次比较优先级,再排分配CPU的队列,按时间片分配CPU,直到进程全部执行完毕。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为输入进程的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
7.根据以上算法编写程序,最后计算平均周转时间与平均带权周转时间。
【注意事项】
动态优先权与静态优先权的区别。
【思考题】
针对某一具体应用环境,如何选择合适的调度算法?
任务三 存储管理
【实训目的】
掌握物理内存和虚拟内存的基本概念;掌握重定位的基本概念及其要点,理解逻辑地址与绝对地址;掌握各种存储管理的实现方法,包括基本原理、地址变换和缺页中断、主存空间的分配及分配算法;掌握常用淘汰算法。
【实训内容】
编写一个模拟的动态页式存储管理程序,实现对动态页式存储的淘汰算法的模拟(在先进先出淘汰算法、最近最少使用淘汰算法、最不经常使用淘汰算法三种算法中至少选择两种进行模拟)并计算各个算法的缺页率;并且页面淘汰算法在淘汰一页时,只将该页在页表中抹去,而不再判断它是否被改写过,也不将它写回到辅存。
【预习要求】
常用的存储管理方法及其基本原理;物理内存与虚拟内存、逻辑地址与绝对地址的概念;常用的淘汰算法。
【实训步骤】
以先进先出淘汰算法为例说明动态页式存储管理的实现过程:
1. 产生一个需要访问的指令地址流,它是一系列需要访问的指令的地址。
为不失一般性,你可以适当地(用人工指定地方法或用随机数产生器)生成这个序列,使得50%的指令是顺序执行的。
25%的指令均匀地散布在前地址部分,25%的地址是均匀地散布在后地址部分;
2. 指定合适的页面尺寸(例如以1K或2K为1页);
3. 指定内存页表的最大长度,并对页表进行初始化;
4. 每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页表未满,则调入一页并打印页表情况;如果该页不足主存且页表已满,则按FIFO页面淘汰算法淘汰一页后调入所需的页,打印页表情况;逐个地址访问,直到所有地址访问完毕。
5. 存储管理算法的流程图如图5所示:
6. 根据图5编写并运行程序,程序运行界面如图6所示。
【注意事项】
页面尺寸的指定;如何选择合适的页面淘汰算法以保证较低的缺页率。
【思考题】
各种不同的页面淘汰算法有哪些优缺点?
为什么会产生页面抖动?
什么是belady现象?
这种现象该如何避免?
图5动态页式存储管理的流程图
图6采用先进先出淘汰算法的动态页式存储管理运行界面
任务四 设备管理
【实训目的】
掌握独占设备的使用方式,以及设备的分配和回收;掌握用死锁避免方法来处理申请独占设备可能造成的死锁。
【实训内容】
用死锁避免方法来处理申请独占设备可能造成的死锁,程序实现对银行家算法的模拟。
【预习要求】
设备的分类;独占设备的分配与回收;处理死锁的方法。
【实训步骤】
1. 设计银行家算法的数据结构:
假设有M个进程N类资源,则有如下数据结构:
MAX[M*N]M个进程对N类资源的最大需求量
AVAILABLE[N]系统可用资源数
ALLOCATION[M*N]M个进程已经得到N类资源的资源量
NEED[M*N]M个进程还需要N类资源的资源量
2. 分析银行家算法的实现过程,流程图如下图7所示:
图7银行算法的实现流程
3. 根据流程图编写程序,部分源代码如下所示:
#include"string.h"
#include
#include
#defineM5
#defineN3
#defineFALSE0
#defineTRUE1
/*M个进程对N类资源最大资源需求量*/
intMAX[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
/*系统可用资源数*/
intAVAILABLE[N]={10,5,7};
/*M个进程对N类资源最大资源需求量*/
intALLOCATION[M][N]={{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
/*M个进程已经得到N类资源的资源量*/
intNEED[M][N]={{7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3}};
/*M个进程还需要N类资源的资源量*/
intRequest[N]={0,0,0};//初始化需要申请的资源数目
voidYinHangJia()//银行家算法的实现
{
inti=0,j=0;
charflag='Y';
voidshowdata();
voidchangdata(int);
voidrstordata(int);
intchkerr(int);
showdata();
while(flag=='Y'||flag=='y')
{
i=-1;
while(i<0||i>=M)
{
printf("请输入需申请资源的进程号(从0到");
printf("%d",M-1);
printf(",否则重输入!
):
");
scanf("%d",&i);
if(i<0||i>=M)printf("输入的进程号不存在,重新输入!
\n");
}
printf("请输入进程");
printf("%d",i);
printf("申请的资源数\n");
for(j=0;j { printf("资源"); printf("%d",j); printf(": "); scanf("%d",&Request[j]); if(Request[j]>NEED[i][j])//第一步判断申请的资源数是否大于需要的资源数 { printf("进程"); printf("%d",i); printf("申请的资源数大于进程"); printf("%d",i); printf("还需要"); printf("%d",j); printf("类资源的资源量! 申请不合理,出错! 请重新选择! \n"); flag='N'; break; } else { if(Request[j]>AVAILABLE[j])//第二步判断申请的资源数是否大于可用资源数 { printf("进程"); printf("%d",i); printf("申请的资源数大于系统可用"); printf("%d",j); printf("类资源的资源量! 申请不合理,出错! 请重新选择! \n"); flag='N'; break; } } } if(flag=='Y'||flag=='y') { changdata(i); if(chkerr(i)) { rstordata(i); showdata(); } else showdata(); } else showdata(); printf("\n"); scanf("%c",&flag); } } voidshowdata() { inti,j; printf("系统可用的资源数为: \n"); printf(""); for(j=0;j printf(" 资源"); printf("%d",j); printf(": "); printf("%d",AVAILABLE[j]); } printf("\n"); printf("各进程还需要的资源量: \n"); for(i=0;i { printf(" 进程"); printf("%d",i); printf(": "); for(j=0;j printf("资源"); printf("%d",j); printf(": "); printf("%d",NEED[i][j]); } printf("\n"); } printf("各进程已经得到的资源量: \n"); for(i=0;i { printf(" 进程"); printf("%d",i); /*printf(": \n");*/ for(j=0;j printf("资源"); printf("%d",j); printf(": "); printf("%d",ALLOCATION[i][j]); } printf("\n"); } } voidchangdata(intk) { intj; for(j=0;j { AVAILABLE[j]=AVAILABLE[j]-Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]+Request[j]; NEED[k][j]=NEED[k][j]-Request[j]; } }; voidrstordata(intk) { intj; for(j=0;j { AVAILABLE[j]=AVAILABLE[j]+Request[j]; ALLOCATION[k][j]=ALLOCATION[k][j]-Request[j]; NEED[k][j]=NEED[k][j]+Request[j]; } }; intchkerr(ints) { intWORK,FINISH[M],temp[M]; inti,j,k=0; for(i=0;i for(j=0;j { WORK=AVAILABLE[j]; i=s; while(i { if(FINISH[i]==FALSE&&NEED[i][j]<=WORK) { WORK=WORK+ALLOCATION[i][j]; FINISH[i]=TRUE; temp[k]=i; k++; i=0; } else { i++; } } for(i=0;i if(FINISH[i]==FALSE) { printf("\n"); printf("系统不安全! ! ! 本次资源申请不成功! ! ! \n"); printf("\n"); return1; } } printf("\n"); printf("经安全性检查,系统安全,本次分配成功。 \n"); printf("\n"); printf("本次安全序列: "); for(i=0;i printf("进程"); printf("%d",temp[i]); printf("->"); } printf("\n"); return0; } 4. 测试并运行程序,运行界面如图8所示: 图8银行家算法运行界面 【注意事项】 独占设备的分配方式。 【思考题】 如果产生了死锁,应如何解除? 任务五 文件管理 【实训目的】 掌握文件的存取方法;掌握文件的逻辑结构和物理结构;掌握存储空间的分配和回收;掌握磁盘管理与调度。 【实训内容】 用程序模拟磁盘的调度过程,并计算各磁盘调度算法包括先来先服务算法、最短寻道时间优先算法、扫描算法和循环扫描算法的平均寻道长度。 【预习要求】 文件的逻辑结构和物理结构;常用的磁盘调度算法。 【实训步骤】 1. 分析常用的磁盘调度算法,熟悉其基本原理。 2. 自行设定起始扫描磁道号及最大磁道号数,程序根据设定值随机产生n个磁道号进行模拟(n也可自行设定); 3. 编写程序实现磁盘调度算法,并显示该算法寻道顺序并计算出寻道总数和平均寻道数;对各种算法的优劣进行比较,得出比较结果。 部分源代码如下所示: #include"stdio.h" #include"stdlib.h" voidCopyL(intSour[],intDist[],intx);//数组Sour复制到数组Dist,复制到x个数 voidSetDI(intDiscL[]); //随机生成磁道数 voidPrint(intPri[],intx); //打印输出数组Pri voidDelInq(intSour[],intx,inty); //数组Sour把x位置的数删除,并把y前面的数向前移动,y后的数保持不变(即会出现2个y) voidFCFS(intHan,intDiscL[]); //先来先服务算法(FCFS) voidSSTF(intHan,intDiscL[]); //最短寻道时间优先算法(SSTF) intSCAN(intHan,intDiscL[],intx,inty); //扫描算法(SCAN) voidCSCAN(intHan,intDiscL[]); //循环扫描算法(CSCAN) voidN_Step_SCAN(intHan1,intDiscL[]); //N步扫描算法 voidPaiXu(); //寻道长度由低到高排序 voidPri(); intNAll=0; intBest[5][2];//用作寻道长度由低到高排序时存放的数组 intLimit=0;//输入寻找的范围磁道数i intJage; floatAver=0; intfa5() { inti; intDiscLine[10]; //声明准备要生成的随机磁道号的数组 intHand; //磁道数 intCon=1; intn; while(Con==1) { Jage=0; printf("\n请输入初始的磁道数(0 "); scanf("%d",&Hand); printf("\n+输入寻找的范围: "); scanf("%d",&Limit); if(Limit>65536){ printf("超出范围! "); } else{ printf(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统实训 操作系统 指导书
![提示](https://static.bdocx.com/images/bang_tan.gif)