模拟抢占式进程调度课程设计说明书.docx
《模拟抢占式进程调度课程设计说明书.docx》由会员分享,可在线阅读,更多相关《模拟抢占式进程调度课程设计说明书.docx(15页珍藏版)》请在冰点文库上搜索。
![模拟抢占式进程调度课程设计说明书.docx](https://file1.bingdoc.com/fileroot1/2023-5/8/8f34fb88-1544-4dab-8287-28cc42fa43e3/8f34fb88-1544-4dab-8287-28cc42fa43e31.gif)
模拟抢占式进程调度课程设计说明书
1.引言
随着科技的发展,计算机已经成为人们工作、学习、生活的必备工具,用户使用计算机处理各种各样的事情。
如何选择合适的进程调度算法使系统能够保证较短的响应时间和较高的吞吐量,使得多个进程竞争CPU时保持公平、高效,是通用操作系统所追求的目标。
进程调度的核心问题是采用什么样的算法把处理机分配给进程,好的算法将提高资源利用率,减少处理机的空闲时间,避免有些作业长期得不到相应的情况发生等,从而设计出受欢迎的操作系统。
较常见的几种进程调度算法有:
先来先服务调度算法;短作业优先调度算法;时间片轮转调度算法;优先级调度算法;高响应比优先算法和多级反馈队列调度算法等。
2.需求分析
2.1设计目的
无论是在批处理系统、分时系统还是实时系统,用户进程数一般都多余处理机数,这将导致用户进程互相争夺处理机。
另外,系统进程也同样需要使用处理机。
、进程调度的主要任务是按照某种策略和方法选取一个处于就绪状态的进程占用处理机。
这次操作系统课程设计要求实现先来先服务、最短作业优先、最高响应比优先和抢占式优先级调度算法并对其性能进行评估,使学生进一步掌握进程调度的概念和算法,加深对处理机分配的理解。
2.2设计内容及要求
(1)设计内容:
以手动或随机方式创建进程放进进程列表中,实现先来先服务、最短作业优先、最高响应比优先和优先级调度算法(采用抢占方式),并实现对调度算法的评估,同时通过用户界面得到更直观的了解。
(2)设计要求:
a)用Java语言编程实现操作模拟操作系统进程调度子系统的基本功能;运用多种算法实现对进程的模拟调度。
b)通过编写程序实现进程或作业先来先服务、高优先权、短作业优先、高响应比优先调度算法。
c)能够计算不同调度算法的平均周转时间和平均等待时间,并进行算法性能的评估。
d)实现用户界面的开发。
2.3算法与设计的思想
(1)算法思想:
a)创建进程
随机创建进程:
随机创建几个进程放在进程列表中
手动创建进程:
通过手动确定要创建进程的相关信息
b)FPF调度算法(采用抢占式)
通过对已创建的进程进行分析,从进程列表中选择一个优先级最高的进程,对其调度,当有权值较高的进程来到时进行抢占,并存储当前进程,当权值较高的进程执行完之后继续执行权值相对较高的进程,运行完之后对该进程在进程视图数组中进行标记,当进程运行结束之后记录结束进程的实际完成时间重复执行该过程直到所有进程都执行完成为止,通过进程视图数组找出每个进程的实际开始时间,最后输出进程视图和比较该算法的必要信息。
c)进程的先来先服务调度算法:
首先扫描当前进程列表,从进程列表中选择一个创建时间最早的进程,然后在屏幕上显示调度情况,待调度后标记这个进程,并记录这个进程的完成时间,重复执行该过程至无进程调度,并记录它们的周转时间、带权周转时间、平均周转时间及平均带权周转时间。
最后输出该算法的一些基本信息。
d)完成最短作业优先调度算法:
通过对已创建的进程进行分析,从进程列表中选择一个运行时间最短的作业,对其调度,运行完之后对该进程在进程视图数组中标记,并且记录进程的结束时间,重复执行该过程并显示出每一进程的执行情况,通过视图数组找出每个进程的实际开始时间,最后输出进程视图和比较该算法的必要信息。
e)高响应比优先调度算法:
这种方法既照顾了短作业,有考虑到了先来先服务,是一种折中的方法。
首先要计算每一个进程的优先权,根据下面这个式子计算:
优先权=(等待时间+要求服务时间)/要求服务时间
找出优先权最大的进程,对其进行调度,运行完成之后标记,并记录它们的周转时间和带权周转时间,最后显示每一进程执行情况。
最后输出改算法的基本信息。
(2)设计思想:
a)每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
b)进程的优先数及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为输入进程的时间。
c)进程的运行时间以时间片为单位进行计算。
d)每个进程的状态可以是就绪W(Wait)、运行R(Run)、或完成F(Finish)三种状态之一。
e)就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
f)如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待CPU。
3.概要设计
本次操作系统课程设计是要实现模拟进程调度,更加直观的看到不同调度算法的调度过程。
在起始阶段,需要以手动或随机方式逐条创建进程,初始化进程的进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态信息,并将初始化后的进程信息显示出来。
选择一种进程调度方式,单击开始调度后,在进程过程显示栏中显示各进程的运行过程,用进度条表示运行状态。
调度执行过程中,可以继续创建进程插入到等待队列中,根据不同算法决定何时执行它。
所有进程运行结束后,显示该算法的运行信息,各进程的到达时间、服务时间、开始执行时间、完成时间、周转时间和带权周转时间。
通过子模块的调用来实现程序的多个子功能。
模块划分如下:
(1)界面设计模块。
用于设计模拟界面,包括进程信息的输入框、显示框、运行情况、调度方法选择下拉菜单、开始、销毁按钮等。
(2)手动创建进程模块。
需要手动输入进程的各项信息,逐条添到列表里。
(3)随机创建进程模块。
逐条创建随机进程并添加到列表里。
(4)先来先服务调度算法模块。
按到达时间决定进程的调度顺序。
(5)最短作业优先调度算法模块。
按作业运行时间的长短决定调度顺序。
(6)高响应比优先调度算法模块。
按作业的响应比决定调度顺序。
(7)抢占式FPF调度算法模块。
当前执行的总是优先级最高的作业。
类和属性的设计:
表1进程类信息(process)属性
字段名
类型
长度
说明
name
string
5
进程名
state
char
1
进程状态,初始为等待W
priority
int/double
优先级或动态优先权
arr_time
int
到达时间
ser_time
int
服务时间
wait_time
int
等待时间
start_time
int
开始执行时间
end_time
int
完成时间
cycling_time
int
周转时间
w_time
float
带权周转时间
4.详细设计
(1)抢占式FPF调度算法的思想:
正在运行的进程是优先级最高的进程,当遇到比当前运行的进程优先级还高的进程,则抢占,即暂停当前运行的进程,开始运行优先级最高的,当这个进程运行完之后,再接运行暂停的那个进程。
(2)抢占式FPF调度算法的流程图
Y
N
图5抢占式FPF调度算法的流程图
(3)算法实现过程:
①MyList类中定义的各个变量来表示一个进程的所有属性,一个MyList对象就是一个进程,但进程名不允许相同,进程名是识别每一个进程的唯一标识,每创建一个进程就加进LinedList中。
②Ftp类继承了JFrame类,实现了Runnable接口,此类实现了进程的两种创建,进程调度(可暂停),进程销毁。
③进程有四个状态,没开始运行时进程的状态为W,表示等待,运行时进程的状态为R,表示运行,应抢占出现暂停时,进程的状态为S,表示当前进程被挂起,当该进程完成调度时,进程状态为F。
④进程调度时,我用进度条来表示进程运行,进度条由40个宽为10的长方形组成,40除以进程的服务时间就是每隔多少秒进度条走一下。
用模拟的时钟来表示进程的到达时间,开始时间,完成时间,最后根据到达时间和完成时间来算出周转时间和平均周转时间。
⑤进程的销毁,选中你要销毁的进程,若进程在运行或尚未运行,则系统会提示此进程不允许销毁,若进程的状态为完成,则此进程与继续销毁,在其他进程运行期间也可以销毁已完成的进程。
5.软件测试
5.1抢占式FPF调度子模块测试过程及原理
(1)测试用例1:
随机创建进程
①测试内容:
随机创建的进程名唯一
②测试数据:
点击随机创建按钮
③预期结果:
进程名唯一
④测试结果:
进程名唯一
图2随机创建进程
(2)测试用例2:
手动创建进程
①测试内容:
手动输入进程名,设置优先级,设置服务时间
②测试数据:
正常数据:
(进程名:
1,优先级:
2,服务时间:
11)
异常数据:
(进程名为空)
(进程名重复,进程名:
1)
③预期结果:
若输入的进程名不重复,则手动创建成功;若进程名为空,则会提示进程名不能为空;若进程名重复,则提示进程名不能重复。
④测试结果:
图3手动创建成功
图4进程名为空
图5进程名重复
(3)测试用例3:
进程运行和暂停
①测试内容:
进程的运行情况
②测试数据:
正常数据:
有可运行的进程,运行过程可暂停
异常数据:
没有可运行的进程
③预期结果:
若有可运行的进程,点击可运行,遇到优先级更高的则出现抢占;若没有可运行的进程,则会目前没有课运行的进程。
④测试结果:
图6有可运行的进程
图7进程运行过程中出现抢占
图8没有可运行的进程
(3)测试用例4:
进程销毁
①测试内容:
进程的销毁
②测试数据:
正常数据:
选中某一行已完成的进程
异常数据:
未选要删除的进程;选中空行;选中正在执行的进程或尚未运行的进程。
③预期结果:
选中某一行已完成的进程,单击单击销毁按钮,则会提示,是否确定销毁,若选择确定,销毁,若选择取消,则不销毁;若未选要删除的进程或选中空行,则会提示请选择进程;选中正在执行的进程或尚未运行的进程,则会提示此进程不允许销毁。
④测试结果:
图9未选需删除的进程或选中空行
图10选中需删除的进程
图11选中正在运行的进程或尚未运行的进程
6.程序清单
1.找出优先级最高的
list1=mlist.Max(lists);
2.将进程的状态改为运行
list1.state="R";
lists.remove(Integer.parseInt(list1.id));
lists.add(Integer.parseInt(list1.id),list1);
jTable1.setValueAt(list1.state,Integer.parseInt(list1.id),2);
3.找出链表中优先级最高的,和当前运行的进程的优先级做比较,若比当前运行的优先级高,做挂起
list2=mlist.Max(lists);
if(list2.name!
=null&&(Integer.parseInt(list2.priority)>Integer.parseInt(list1.priority))&&(list2.state=="W"||list2.state=="R"))
{
list1.state="S";
jTable1.setValueAt(list1.state,Integer.parseInt(list1.id),2);
lists.remove(Integer.parseInt(list1.id));
lists.add(Integer.parseInt(list1.id),list1);
try{
synchronized(t1){
t1.wait();
}
}
catch(Exceptione){}
}
4.激活挂起的进程
try{
synchronized(t1){
t1.notify();
list1.state="R";
jTable1.setValueAt(list1.state,Integer.parseInt(list1.id),2);
lists.remove(Integer.parseInt(list1.id));
lists.add(Integer.parseInt(list1.id),list1);
bool=false;
}
}
catch(Exceptione){}
5.进程创建
(1)手动创建
Stringstate="W";
Stringname=jTextField1.getText().trim();
Stringpriority=jSpinner1.getValue().toString();
Stringrun_time=jSpinner2.getValue().toString();
try{
intb=Integer.parseInt(priority);
}
catch(Exceptione){
priority=String.valueOf((int)((Math.random()*5)+1));
}
try{
inta=Integer.parseInt(run_time);
}
catch(Exceptione){
run_time=String.valueOf((int)((Math.random()*15)+1));
}
if(name.equals(""))
JOptionPane.showMessageDialog(this,"进程名不能为空!
","提示",JOptionPane.WARNING_MESSAGE);
else{
booleanb=newMyList().Judge(lists,name);//判断进程名是否冲突
if(!
b)
{
JOptionPane.showMessageDialog(this,"进程名不能重复!
","提示",JOptionPane.WARNING_MESSAGE);
jTextField1.setText("");
}
else{
jTable1.setValueAt(name,row,0);
jTable1.setValueAt(priority,row,1);
jTable1.setValueAt(state,row,2);
jTable1.setValueAt(time,row,3);
jTable1.setValueAt(run_time,row,4);
row++;
MyListlist=newMyList();
list.id=String.valueOf(row-1);
list.name=name;
list.priority=priority;
list.state=state;
list.arr_time=String.valueOf(time);
list.ser_time=run_time;
lists.add(list);
if(j==0){
list1=mlist.Max(lists);
}
jTextField1.setText("");
}
}
(2)随机创建
MyListrlist=newMyList();
rlist=newEvent().getRound(lists);
rlist.id=String.valueOf(row);
rlist.arr_time=String.valueOf(time);
jTable1.setValueAt(rlist.name,row,0);
jTable1.setValueAt(rlist.priority,row,1);
jTable1.setValueAt(rlist.state,row,2);
jTable1.setValueAt(rlist.arr_time,row,3);
jTable1.setValueAt(rlist.ser_time,row,4);
row++;
lists.add(rlist);
if(j==0){
list1=mlist.Max(lists);
}
try{
Thread.sleep(300);
jButton1.setEnabled(false);
}catch(InterruptedExceptionex){
Logger.getLogger(Fpf.class.getName()).log(Level.SEVERE,null,ex);
}
jButton1.setEnabled(true)
7.参考资料
[1]汤子瀛,汤小丹.计算机操作系统.西安电子科技大学出版社.陕西西安.2001.
[2]耿祥义,张跃平.java2实用教程.清华大学出版社.北京.2006.
[3]SharonZakhour,ScottHommel.java教程.人民邮电出版社.北京.2007.
[4]杨树林,胡洁萍.java语言最新实用案例教程.清华大学出版社.北京.2010.