os实验报告.docx
- 文档编号:5514386
- 上传时间:2022-12-17
- 格式:DOCX
- 页数:42
- 大小:781.66KB
os实验报告.docx
《os实验报告.docx》由会员分享,可在线阅读,更多相关《os实验报告.docx(42页珍藏版)》请在冰豆网上搜索。
操作系统原理
实验报告
学生姓名
学号
专业班级
指导教师
郑美光
学院
计算机学院
完成时间
2020.06.10
目录
一实验概述 1
(一)实验目的 1
(二)实验内容及要求 1
1.实验内容 1
2.实验具体要求 1
二需求分析 2
(一)需求分类 2
(二)具体需求 2
1.数据结构 2
2.处理机 3
3.内存分配 3
4.可视化 3
5.模块之间的联系 4
三总体设计 5
(一)总体设计思路 5
1.任务分解 5
2.整体流程 5
3.互斥的处理 5
4.并行的实现 5
5.语言的选择 5
四详细设计与实现 7
(一)数据结构 7
1.PCB 7
2.队列 11
(二)处理机模块实现 11
1.数据成员 11
2.函数成员 12
(三)内存分配模块实现 21
(四)可视化界面模块实现 24
五实验运行结果 36
结束语 39
参考文献 40
一实验概述
(一)实验目的
多道系统中,进程与进程之间存在同步与互斥关系。
当就绪进程数大于处理机数时,需按照某种策略决定哪些进程先占用处理机。
在可变分区管理方式下,采用首次适应算法实现主存空间的分配和回收。
本实验模拟实现处理机调度及内存分配及回收机制,以对处理机调度的工作原理以及内存管理的工作过程进行更深入的了解。
(二)实验内容及要求
1.实验内容
(1)选择一个调度算法,实现处理机调度;
(2)结合
(1)实现主存储器空间的分配和回收。
2.实验具体要求
(1)设计一个抢占式优先权调度算法实现多处理机调度的程序,并且实现在可变分区管理方式下,采用首次适应算法实现主存空间的分配和回收。
(2)PCB内容包括:
进程名/PID;要求运行时间(单位时间);优先权;状态;进程属性:
独立进程、同步进程(前趋、后继)。
(3)可以随机输入若干进程,可随时添加进程,并按优先权排序。
(4)从就绪队首选进程运行:
优先权-1;要求运行时间-1;要求运行时间为0时,撤销该进程;一个时间片结束后重新排序,进行下轮调度;
(5)考虑两个处理机,考虑同步进程的处理机分配问题,每次调度后,显示各进程状态,运行进程要显示在哪个处理机上执行。
(6)规定道数,设置后备队列和挂起状态。
若内存中进程少于规定道数,可自动从后备队列调度一作业进入。
被挂起进程入挂起队列,设置解挂功能用于将制定挂起进程解挂入就绪队列。
(7)结合实验一PCB增加所需主存大小,主存起始位置(由作业调度分配内存);采用首次适应算法分配主存空间。
(8)自行假设主存空间大小,预设操作系统所占大小并构造未分分区表。
表目内容:
起址、长度、状态(未分/空表目)。
(9)进程完成后,回收主存,并与相邻空闲分区合并。
(9)最好采用图形界面;
二需求分析
(一)需求分类
通过分析实验要求,可知实验主要分为五大方面的需求:
数据结构、处理机、内存分配、可视化,模块之间的联系。
数据结构主要实现PCB的定义。
处理机主要实现作业调度以及进程调度。
内存分配主要实现内存空间的分配以及回收,回收过程中能够合并相邻空闲分区。
可视化主要实现各作业或进程状态的可视,内存空间使用状况的可视,还需要提供添加作业的窗口、挂起与解挂操作的窗口。
模块之间的联系包含各模块任务之间的相互配合或相互制约等需求。
(二)具体需求
1.数据结构
PCB的内容包括PID,运行时间,优先权,状态,前趋,后继,在内存中的起始位置,需要的内存空间的大小。
要能够区分独立进程和同步进程。
(1)PID是进程的唯一性标识,因此各进程的PID不允许重复。
另外,用户不需要输入PID,当一个作业由作业调度选中进入内存后,自动被分配PID。
(2)要求运行时间设置为进程需要的时间片个数,在CPU中的进程每次只能运行一个时间片,完成后时间片个数减一。
(3)优先权用优先数表示,优先数是非负整数,优先数的数值越小,优先级越高。
进程运行完一个时间片后,优先数加一。
(4)进程状态包括就绪状态(ready),运行状态(running),阻塞状态(block),挂起状态(suspend),完成状态(finished)。
处于后备队列的作业,没有被分配PID和内存空间,处于后备状态(reverse)。
实际上作业不具有PCB,PCB是进程存在的唯一标识,在这里出于模拟的需要,为提交的作业先行构建PCB,以存储有关优先级和运行时间等的信息。
(5)进程的属性分为独立进程、同步进程,同步进程是有前趋或者后继的进程,PCB中的前趋记录前趋进程的PID,后继记录后继进程的PID。
(6)内存由多个一定大小的块构成,块按排列顺序编号。
采用连续的方式存储,在内存中的起始位置就是进程所占块的编号的最小值。
需要内存空间大小用需要块的个数表示。
(7)运行函数。
当进程处于running状态时,运行该函数。
该函数的功能包括休眠单位时间片时间(模拟进程运行),减少当前进程需要时间片个数,增加优先数。
2.处理机
(1)实现作业调度。
作业调度指从外存的后备队列选取某些作业,调入内存,为他们创建进程,分配资源,插入就绪队列中。
本实验中所有的作业被提交后均进入后备队列,作业调度为作业分配内存空间和PCB,使之成为进程。
当就绪队列中的进程数少于道数的时候,作业调度自动将后备队列的作业调入。
按照作业优先级的顺序调度,当某作业需要的内存空间不能满足时,将该作业移到后备队列的队尾。
(2)实现进程调度。
按优先级对进程排序、调度。
由于具有两个处理机,因此理论上应该实现两个进程的并行。
两个处理机共用就绪队列,阻塞队列,挂起队列,完成队列,采用相同的进程调度规则(按优先级调度),因此上述三个队列是临界资源,需要考虑互斥问题。
两个处理机共同调度还应该考虑进程的同步问题,即当一个进程的前趋未运行完成时,该进程会进入阻塞状态,等待前趋进程的完成。
当前趋进程完成的时候,处于阻塞队列的进程立即进入就绪队列。
3.内存分配
(1)设定主存空间大小为内存块的数目。
(2)预设操作系统所占大小,为操作系统分配固定位置的内存空间。
(3)构造未分分区表,表目需包括以下信息:
起址、长度、状态(占用或未占用)。
4.可视化
主要实现各作业或进程状态的可视,内存空间使用状况的可视,还需要提供添加作业的窗口、挂起与解挂操作的窗口。
(1)显示后备队列中各作业的有关信息,包括需要时间数,优先级,前趋,需要内存空间数。
(2)显示就绪队列,阻塞队列,挂起队列中进程的有关信息,包括PID,需要时间数,优先级,前趋,需要内存空间数的信息。
(3)显示两个处理机CPU正在运行的进程情况。
(4)显示内存空间的使用情况。
内存块上显示占用该内存块的进程的PID。
内存块数量表示该进程所需的内存空间的大小。
(5)提供添加作业的窗口,输入作业的需要时间数,优先数,前趋,需要内存空间数即可提交一个作业。
(6)提供挂起与解挂操作的窗口。
在挂起窗口输入需要挂起的进程的PID,该进程会进入挂起队列,进程的部分内存空间被回收,仅在内存中保留该进程占用的第一个内存块;在解挂窗口输入需要解挂的PID,会根据内存的具体情况将进程调回就绪队列或保留在挂起队列。
(7)提供错误提示信息。
如解挂后的进程需要直接进入就绪队列,存在内存不足的情况,因此需要提示“内存不足,无法解挂进入就绪队列”。
(8)设置结束键,当按下结束键时,处理机结束工作。
(9)界面布局良好。
5.模块之间的联系
(1)作业调度、进程调度、窗体显示、添加进程、挂起或解挂进程应当实现宏观上的并行。
即需要实现在窗体上添加作业或挂起、解挂进程时不影响原有进程的调度和运行;窗体能够实现动态的刷新,及时更新信息。
(2)作业调度需要为进程分配内存空间,同时进程完成后需要回收内存资源,因此存在处理机和内存分配的配合;挂起进程需要回收部分内存资源,解挂需要再分配内存资源,因此存在挂起解挂功能与内存分配的配合。
三总体设计
(一)总体设计思路
1.任务分解
将实验分解为四部分,数据结构、处理机、内存分配、可视化的图形界面,分模块实现各部分的主要功能。
再处理各个模块之间的通信,使各模块相互配合,成为有机的整体,实现上述各种需求。
2.整体流程
主要的工作流程是:
输入作业的时间数、优先级等信息,创建作业→进入后备队列→由作业调度为作业创建进程,分配资源(本实验中主要是内存资源),创建PCB→进入就绪队列→循环进行进程调度→某进程完成→回收内存,将阻塞的后继进程调回就绪队列→循环进行程序调度……
3.互斥的处理
对于互斥的资源,如两个处理机共用的就绪队列,阻塞队列分别设置锁,当一个处理机对某个队列进行排序、插入元素、修改元素、删除元素等操作时,另一个处理机不能同时操作相同的队列。
4.并行的实现
实现作业调度、双处理机进程调度、内存分配、挂起与解挂、作业提交、图形界面的刷新等功能的宏观上的并行,采用多线程的方式。
线程是可以由CPU直接运行的实体,单CPU同一时刻只能运行一个进程,但一个进程可以创建多个线程,各线程可以共享CPU。
为作业调度、图形界面显示(内含挂起与解挂、作业提交功能)以及两个处理机上的两个进程调度分别创建线程,以实现上述功能宏观上的并行执行。
5.语言的选择
实验采用Java语言编写,以便较方便地实现多线程和图形化界面展示。
而实际的操作系统大多由C语言编写而成。
(二)开始
提交作业
作业调度
是
进程调度
插入完成队列
进入就绪队列
内存满足?
该作业移至后备队列队尾
是否有前趋?
进入阻塞队列
进入挂起队列
解挂
运行时间减一
优先级减一
运行时间为0?
回收内存,解除后继的阻塞状态
所有进程完成?
结束
是否挂起?
前趋完成?
留在阻塞队列
是
否
否
是
是
否
是
否
否
是
总体工作流程图
图3-1总体工作流程图
四详细设计与实现
(一)数据结构
1.PCB
创建一个新类,命名为PCB。
PCB有PID,运行时间,优先权,状态,前趋,后继,在内存中的起始位置,需要的内存空间的大小等数据成员以及各种方法成员。
(1)PID的数据类型为int型,初始化值为-1,-1即表示还未分配PID,将由作业调度分配一个唯一的自然数。
(2)要求运行时间的数据类型为int型,为正整数。
(3)优先数的表示优先权,数据类型为int型,优先数是非负整数,优先数的数值越小,优先级越高。
(4)进程状态的数据类型为int型,0表示就绪状态(ready),1表示运行状态(running),2表示阻塞状态(block),3表示后备状态(reverse),4表示挂起状态(suspend),5表示完成状态(finish)。
初始化值为3,即作业一经提交即进入后备队列。
(5)前趋的数据类型为int型,记录前趋进程的PID。
(6)后继的数据类型为int型,记录后继进程的PID。
(7)内存起始位置的数据类型为int型,采用连续的方式存储,进程在内存中的起始位置就是进程所占块的编号的最小值。
(8)需要内存空间的大小数据类型为int型,表示用需要到的内存块的个数。
(9)构造函数。
用于PCB类对象的创建
(10)各参数的赋值函数和获值函数。
PCB中的数据成员应当设置为私有的,应当提供函数实现对PID等数据成员的赋值或者取值。
(11)运行函数。
当进程处于running状态时,运行该函数。
该函数的功能包括显示当前所处的处理机(双处理机调度,需显示是在哪个处理机上运行),休眠单位时间片时间(模拟进程运行),当前进程需要时间片个数减一,优先数加一。
具体代码如下:
publicclassPCB{
privateintPID=-1;//进程标识,为正整数
privateinttime;//进程所需时间,为正整数
privateintpriority;//进程优先级
privateintstate=3;/*进程的状态
*0ready;1running;2block;3reverse;4suspend;5finished*/
privateintpredecessor;//前趋PID
privateintsuccessor=0;//后继PID
privateintlocation;//在内存中的起始位置
privateintsize;//在内存中需要的空间
PCB(){}//无参的构造函数
PCB(inttime,intpriority,intpredecessor,intsize){//含参的构造函数,用于添加作业
this.time=time;
this.priority=priority;
this.predecessor=predecessor;
this.size=size;
}
publicvoidsetPID(intpid){//设置PID的值
PID=pid;
}
publicintgetPID(){//获取PID的值
returnPID;
}
publicvoidsetSize(intsz){//设置需要内存空间的值
size=sz;
}
publicintgetSize(){//获取需要内存空间的值
returnsize;
}
publicvoidsetLocation(intloc){//设置内存中起始位置的值
location=loc;
}
publicintgetLocation(){//获取内存中起始位置的值
returnlocation;
}
publicvoidsetTime(inttime){//设置要求运行时间的值
this.time=time;
}
publicintgetTime(){//获取要求运行时间的值
returntime;
}
publicvoidsetPriority(intpri){//设置优先数的值
priority=pri;
}
publicintgetPriority(){//获取优先数的值
returnpriority;
}
publicvoidsetState(intstate){//设置进程状态的值
this.state=state;
}
publicintgetState(){//获取进程状态的值
returnstate;
}
publicvoidsetPre(intpre){//设置前趋PID的值
predecessor=pre;
}
publicintgetPre(){//获取前趋PID的值
returnpredecessor;
}
publicvoidsetSuc(intsuc){//设置后继PID的值
successor=suc;
}
publicintgetSuc(){//获取后继PID的值
returnsuccessor;
}
publicvoidone_slice(){//运行函数
if(time>0)
time--;//时间片减一
if(Thread.currentThread().getName()=="pro_sche1"){
Window.jt_running1.setText(PID+"正在执行"+"剩余时间:
"+time+""+"优先级:
"+priority);//若是处理机1调度,则在表示处理机1的文本框中显示信息
try{
Thread.sleep(4000);
}
catch(Exceptionex){}
Window.jt_running1.setText("");
priority++;
}
else{
Window.jt_running2.setText(PID+"正在执行"+"剩余时间:
"+time+""+"优先级:
"+priority);//若是处理机2调度,则在表示处理机2的文本框中显示信息
try{
Thread.sleep(4000);
}
catch(Exceptionex){}
Window.jt_running2.setText("");
priority++;
}
}
}
2.队列
队列包括后备队列,挂起队列,就绪队列,阻塞队列,完成队列。
采用ArrayList
ArrayList
数组一旦创建,长度固定,但是ArrayList
因此可以利用ArrayList
具体代码如下:
publicclassprocessorextendsThread{
staticArrayList
staticArrayList
staticArrayList
staticArrayList
staticArrayList
… }
(二)处理机模块函数实现
创建processor类,继承Thread类以实现多线程。
1.数据成员
(1)创建一个新类,命名为PCB。
PCB有PID,运行时间,优先权,状态,前趋,后继,在内存中的起始位置,需要的内存空间的大小等数据成员以及各种方法成员。
(2)队列。
包括后备队列,挂起队列,就绪队列,阻塞队列,完成队列。
其中模拟两个处理机的两个进程调度线程会对共享的就绪队列、阻塞队列、完成队列进行插入、删除、排序等的操作,因而这三个队列是临界资源。
(3)锁。
为防止两个进程调度线程同时对同一队列操作,分别为三个队列设置相应的锁。
(4)PID计数器。
用于为每一个进程分配唯一的PID,每分配一个,计数器的数值加一。
2.函数成员
(1)排序函数。
由于作业调度或者进程调度均需要按照优先级调度,因此需要排序函数对某一队列的元素进行排序,采用冒泡排序法。
(2)PID分配函数。
用于作业调度创建进程时,分配PID。
(3)found函数。
用来确定某一队列中是否具有某个PCB。
主要用来判断一个进程的前趋进程是否在完成队列当中,如果在,说明前趋进程已经完成,则该进程不需要被阻塞。
(4)run函数。
是继承于父类Thread的函数,重写该函数以实现多线程,实现作业调度和进程调度的并行。
run函数具体实现了作业调度和进程调度。
作业调度:
为作业创建进程,分配内存,创建PCB,插入就绪队列当中。
按照优先级排序调度。
假定处理机的道数为5,当就绪队列中的进程数少于5并且后备队列中有作业时,作业调度会自动为作业创建进程。
在创建进程之前先要判断需要的内存空间是否大于现有的可用内存空间,如果不大于,则创建进程,如果大于,则将该作业移至后备队列的队尾,进行下一轮作业调度。
进程调度:
为位于就绪队列的各进程分配CPU资源。
按照优先级排序调度。
共创建两个进程调度线程,以模拟两个处理机上的调度。
调度分为以下几种情况:
A.就绪队列中的进程数等于道数或者就绪队列中的进程数小于道数但后备队列中已经没有作业。
此时不要需要进行作业调度增加就绪队列中的进程数,选中优先级最高的进程,判断是否有前趋未完成,如果有则该进程进入阻塞队列,并且从就绪队列中移除;如果没有,继续判断该进程的状态,如果是运行状态,说明该进程正在另一个处理机上运行,则转而调度优先级次于该进程的下一进程;如果不是运行状态,则进入CPU,运行一个时间片(此时由函数设置时间片和优先级的变化),设置状态位为运行状态。
运行完毕后检查时间片是否为0,如果为0,则回收该进程的内存,将该进程PCB加入完成队列当中,并将PCB从就绪队列中移除。
将该进程处于阻塞队列的后继进程调入就绪队列当中;如果不为0,则设置状态位为就绪状态,重回就绪队列当中,等待下一次调度。
B.就绪队列中进程数少于道数且后备队列中有作业时,进程调度休眠一段时间,等待作业调度。
C.就绪队列和后备队列均为空,此时处理机没有可以运行的任务,休眠,等待作业的提交。
作业调度、进程调度流程图如下:
后备队列排序
是
插入就绪队列
分配PCB
分配内存
内存条件满足?
该作业移至后备队列队尾
否
开始
选中第一个作业
就绪队列不满且
后备队列不空?
休眠
是
否
处理机停止工作?
结束
是
否
图4-1作业调度流程图
开始
就绪队列排序
是
运行一个时间片
选优先级最高进程
①?
时间数为0?
等待作业调度
时间数-1,优先数+1
回收内存,解除后继进程的阻塞,
移出就绪队列,进入完成队列
处理机工作?
是
否
否
是
是
否
是
否
否
是
②?
③?
结束
①就绪队列中进程数=道数||就绪队列中进程数<道数且后备队列无作业
②无前趋或前趋完成
③进程状态为运行态
④就绪队列中道数不满且后备队列不为空
⑤就绪队列和后备队列均为空
④?
休眠
⑤?
进入阻塞队列
是
图4-2进程调度流程图
具体代码如下:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- os 实验 报告