操作系统课程设计报告.docx
《操作系统课程设计报告.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告.docx(54页珍藏版)》请在冰豆网上搜索。
![操作系统课程设计报告.docx](https://file1.bdocx.com/fileroot1/2023-1/21/878ec720-c315-4cf4-9a08-428172e2b6c2/878ec720-c315-4cf4-9a08-428172e2b6c21.gif)
操作系统课程设计报告
操作系统课程设计报告
题目:
采用时间片轮转算法的进程调度程序
专业
学生姓名
班级
学号
指导教师
完成日期
2016年6月17日
6.1完整扥程序代码……………………………………………………………………….12
6.2主要/关键算法的程序清单……………………………………………………………34
一、课程设计目的
《操作系统》是一门重要的专业基础课,是涉及较多硬件知识的计算机系统软件课程。
在计算机软硬件课程的设置上,它起着承上启下的作用。
操作系统对计算机系统资源实施管理,是所有其他软件与计算机硬件的唯一接口,所有用户在使用计算机时都要得到操作系统提供的服务。
操作系统课程设计的主要任务是研究计算机操作系统的基本原理和算法,掌握操作系统的进程管理、存储管理、文件管理和设备管理的基本原理与主要算法。
目的是使学生掌握常用操作系统(如DOS、Windows或Linux)的一般管理方法,了解它是如何组织和运作的,对操作系统的核心概念和算法有一个透彻的理解,并对系统运行的机制有一个全面的掌握,从而充分理解系统调用与程序设计之间的关系。
进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。
同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。
二、课程设计内容与要求
2.1设计目的
在多道程序和多任务系统中,系统内同时处于就绪状态的进程可能有若干个,且进程之间也存在着同步与互斥的关系,要求采用指定的调度策略,使系统中的进程有条不紊地工作,通过观察诸进程的运行过程,以巩固和加深处理机调度的概念。
2.2设计要求(多道、单处理机)
1)每一个进程有一个PCB,其内容可以根据具体情况设定。
2)可以在界面设定的互斥资源(包括两种:
输入设备与输出设备)的数目
3)进程数、进入内存时间、要求服务时间可以在界面上进行设定
4)进程之间存在一定的同步与互斥关系,可以通过界面进行设定,其表示方法如下:
进程的服务时间由三段组成:
I2C10O5(表示进程的服务时间由2个时间片的输入,10个时间片的计算,5个时间片的输出)
进程间的同步关系用一个段表示:
W2,表示该进程先要等待P2进程执行结束后才可以运行
因此,进程间的同步与互斥关系、服务时间可以统一用四段表示为:
I2C10O5W2
5)可以在运行中显示各进程的状态:
就绪、阻塞、执行
6)采用可视化界面,可在进程调度过程中随时暂停调度,查看当前进程的状态以及相应的阻塞队列
7)具有一定的数据容错性
三、系统分析与设计
3.1系统分析
在早期的的时间片轮转算法中,系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时,把CPU分配给队首进程,并令其执行一个时间片。
当执行的时间片用完时,由一个计时器发出中断请求,调度程序便根据此信号来终止该进程的执行,并将它送到就绪队列的末尾。
然后,再把处理机分配给就绪队列中新的队首进程,同时让它执行一个时间片。
这样就可以保证就绪队列中的所有进程在一个给定的时间内均能获得一个时间片的处理机执行时间。
3.2系统设计
3.2.1模块设计
3.2.2数据结构说明
此次设计用到了LinkedList和HashMap。
Linkedlist:
此次程序编写过程中把链表当成一个队列来用,采用时间片轮转算法在就绪队列中选择要运行的进程时总是取第一个进程执行,而将时间片用完总是添加到就绪队列尾端,因此用LinkedList较为合适。
HashMap:
要保证进程之间同步则必须清楚的知道任意时刻每个进程的执行情况,而在进程调度过程中,你并不知道任意时刻进程处于什么状态。
为此,把所有进程以它们的进程号作为关键字加入到HashMap中,则可以做到在任意时刻通过进程的进程号找到该进程,从而可以检查它的执行状态。
3.2.3算法流程图
四、系统测试与调试分析
4.1系统测试
测试说明
测试名称
采用时间片轮转算法的进程调度程序
测试目的
验证调度的正确性
测试技术
功能测试
测试方法
黑盒测试法
测试用例
测试内容
验证调度是否正确
测试步骤
设置输入、输出设备以及进程数目
设置或导入每个进程名称、开始时间、服务时间
设置时间片大小
点击“开始”,开始调度
测试数据
预期结果
进程名|输入设备|CPU|输出设备|互斥关系|开始时间|已输入|已输出|已用时间片|已用CPU|完成|周转|带权周转时间|状态
200005612416112.75true
300023542642396.5true
1000212661251504.17true
4000361625595310.6true
5000142436666210.33true
测试结果
与预期结果相符
运行记录
开始执行。
。
。
第5秒:
进程2添加到就绪队列
第5秒:
执行进程2
第5秒:
进程2输入阻塞!
第5秒:
进程2获得输入设备
第10秒:
进程2输入完成,转入就绪队列
第10秒:
进程2释放输入设备
第11秒:
执行进程2
第14秒:
进程2时间片用完,转入就绪队列队尾,继续等待执行
第15秒:
执行进程2
第15秒:
进程2输出阻塞!
第15秒:
进程2获得输出设备
第15秒:
进程2输出完成,转入就绪队列
第15秒:
进程2释放输出设备
第16秒:
执行进程2
第16秒:
进程2执行完毕,转入完成队列!
第17秒:
进程1添加到就绪队列
第17秒:
进程3添加到就绪队列
第17秒:
执行进程1
第17秒:
进程1输入阻塞!
第17秒:
进程1获得输入设备
第18秒:
执行进程3
第18秒:
进程3输入阻塞!
第18秒:
进程1输入完成,转入就绪队列
第18秒:
进程1释放输入设备
第18秒:
进程3获得输入设备
第19秒:
执行进程1
第21秒:
进程1时间片用完,转入就绪队列队尾,继续等待执行
第22秒:
执行进程1
第22秒:
进程3输入完成,转入就绪队列
第22秒:
进程3释放输入设备
第25秒:
进程1时间片用完,转入就绪队列队尾,继续等待执行
第26秒:
执行进程3
第29秒:
进程3时间片用完,转入就绪队列队尾,继续等待执行
第30秒:
执行进程1
第33秒:
进程1时间片用完,转入就绪队列队尾,继续等待执行
第34秒:
执行进程3
第36秒:
进程3输出阻塞!
第36秒:
进程3获得输出设备
第37秒:
执行进程1
第37秒:
进程1时间片用完,转入就绪队列队尾,继续等待执行
第38秒:
执行进程1
第39秒:
进程3输出完成,转入就绪队列
第39秒:
进程3释放输出设备
第41秒:
进程1时间片用完,转入就绪队列队尾,继续等待执行
第42秒:
执行进程3
第42秒:
进程3执行完毕,转入完成队列!
第43秒:
进程4添加到就绪队列
第43秒:
执行进程1
第43秒:
进程1输出阻塞!
第43秒:
进程1获得输出设备
第44秒:
执行进程4
第44秒:
进程4输入阻塞!
第44秒:
进程4获得输入设备
第44秒:
进程4输入完成,转入就绪队列
第44秒:
进程4释放输入设备
第45秒:
执行进程4
第47秒:
进程4时间片用完,转入就绪队列队尾,继续等待执行
第48秒:
执行进程4
第48秒:
进程1输出完成,转入就绪队列
第48秒:
进程1释放输出设备
第50秒:
进程4输出阻塞!
第50秒:
进程4获得输出设备
第51秒:
执行进程1
第51秒:
进程1执行完毕,转入完成队列!
第52秒:
进程5添加到就绪队列
第52秒:
执行进程5
第52秒:
进程5输入阻塞!
第52秒:
进程5获得输入设备
第53秒:
进程5输入完成,转入就绪队列
第53秒:
进程5释放输入设备
第54秒:
执行进程5
第54秒:
进程5时间片用完,转入就绪队列队尾,继续等待执行
第55秒:
执行进程5
第55秒:
进程4输出完成,转入就绪队列
第55秒:
进程4释放输出设备
第58秒:
进程5时间片用完,转入就绪队列队尾,继续等待执行
第59秒:
执行进程4
第59秒:
进程4执行完毕,转入完成队列!
第60秒:
执行进程5
第62秒:
进程5输出阻塞!
第62秒:
进程5获得输出设备
第65秒:
进程5输出完成,转入就绪队列
第65秒:
进程5释放输出设备
第66秒:
执行进程5
第66秒:
进程5执行完毕,转入完成队列!
第66秒:
所有进程已执行完毕,用时66秒!
4.2调试分析
4.2.1实际完成的情况说明
实现采用时间片轮转算法的进程调度程序的全部功能,简单实现了采用短作业优先算法的进程调度程序和采用高响应比优先算法的进程调度程序,可以正确调度进程并在调度过程中检测进程状态。
可以检测死锁,并给出警告。
调度执行完成后,可以计算平均周转时间和平均带权周转时间。
4.2.2程序的性能分析
程序窗口在打开过程中会有闪烁,但在最小化窗口并还原之后便可正常显示,对程序执行没有影响。
4.2.3出现的问题及其解决方案
由于刚开始在设计过程中对进程的调度没有一个整体的认识,导致在进行进程状态转换阶段程序编写的思路不清晰,走了很多弯路。
解决方案:
查看课本,仔细分析进程的五种基本状态及转换,采用模块法编写程序。
五、用户手册
5.1使用平台
是Eclipse。
下载网址:
http:
//www.eclipse.org/downloads/
5.2安装平台
Eclipse是一个开放源代码的软件开发项目,不需要安装,只需将下载下来的压缩包解压到指定位置,然后点击“eclipse.exe”即可运行。
5.3使用说明
1)打开eclipse后,在项目区单击右键,选择Import,打开下面对话框
2)选择“ExistingProjectsintoWorkspace”,然后点击“Next”
3)选中“Selectrootdirectory”,然后点击“Browse”
4)找到解压后项目存在的文件夹,选中后点击“确定”,即可成功将项目导入。
5)打开“Main.java”,右键选择“RunAs”,单击“JavaApplication”,即可运行。
6)设置输入、输出设备以及进程的的数目,直接回车或者单击“确定”
7)为每个进程设置进程名、开始时间以及服务时间(注意:
也可导入样例数据,但是此时进程数不可超过20)。
8)设置时间片大小(此步可省略,默认时间片大小为3S)
9)单击开始,模拟调度则开始进行,调度进行过程中可随时暂停调度以便查看当前状态。
10)所有进程执行完成后,可以选择“导出文件”来导出并保存调度运行记录
11)点击“重置”,则重新开始运行程序,如不需要重新执行,直接退出程序即可。
六、程序清单
6.1完整的程序代码
packagepvt.mbc.main;
importpvt.mbc.mainframe.MainFrame;
publicclassMain{
/**
*@paramargs
*/
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
MainFramemainFrame;
mainFrame=newMainFrame();
mainFrame.run();
}
}
packagepvt.mbc.mainframe;
importjava.awt.Button;
importjava.awt.Color;
importjava.awt.Container;
importjava.awt.Label;
importjava.awt.TextArea;
importjava.awt.TextField;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.ItemEvent;
importjava.awt.event.ItemListener;
importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.text.NumberFormat;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importjava.util.HashMap;
importjava.util.Iterator;
importjava.util.LinkedList;
importjava.util.Map;
importjavax.swing.JComboBox;
importjavax.swing.JFileChooser;
importjavax.swing.JFrame;
importjavax.swing.JOptionPane;
importjavax.swing.JTable;
importjavax.swing.filechooser.FileNameExtensionFilter;
importpvt.mbc.pcb.Process;
、publicclassMainFrameextendsJFrameimplementsActionListener,ItemListener{
staticintproID=1;//进程编号,1~n
staticintt;
staticinttime;
//privateThreadrunThread;
privatestaticfinallongserialVersionUID=1L;
JFileChooserjFileChooser;
BufferedWriterbWriter;
FileWriterfileWriter;
FileNameExtensionFilterfilter;
inti;//系统运行时间
booleanstart=false;
ButtonstartButton,suspendButton,continueButton;
Containercontainer;
TextFieldprocountField,proentertimeField,servetimeField;
Labelprocount,proentertime,servetime;
LabelindeviceJLabel;
LabeloutdeviceJLabel;
TextFieldinField,outField,processnameField;
JTabletable;
ButtonionumokButton,processSetButton,datainputButton;
LabelnoticeJLabel,processnameLabel;
LabeltimepiceLabel;
LabelroundLabel,proundLabel;
TextFieldroundField,proundField;
TextFieldtimepiceField;
intpcbnumber;//进程数目
intinnumber;//输入设备数目
intoutnumber;//输出设备数目
inttimepice=3;//默认为3s
ButtontimeokButton;
Labelhoubei,ready,block,finish,onrun;
TextAreahoubeiArea;
TextAreafinishArea;
JComboBoxchoiceBox;
TextAreareadyArea;
TextAreablookArea;
TextAreaonrunArea;
TextAreashowstateArea;
LinkedListhoubeiList;
LinkedListreadyList;
LinkedListblockList;
LinkedListfinishList;
ProcessonrunProcess;
MapsysMap;
ButtonresetButton;
ButtondataoutButton;
intindex=0;
publicMainFrame(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("采用时间片轮转算法的进程调度程序");
setBounds(0,0,1366,730);
setVisible(true);
init();
}
publicvoidinit(){
//TODOAuto-generatedmethodstub
//mianFrame=newJFrame("采用时间片轮转算法的进程调度程序");
jFileChooser=newJFileChooser();
filter=newFileNameExtensionFilter("运行结果保存","txt");
jFileChooser.setFileFilter(filter);
sysMap=newHashMap();
houbeiList=newLinkedList();
readyList=newLinkedList();
blockList=newLinkedList();
onrunProcess=null;
finishList=newLinkedList();
//pause=false;
time=timepice;
container=newContainer();
container.setLayout(null);
resetButton=newButton("重置");
resetButton.setBounds(480,575,50,25);
resetButton.setBackground(Color.green);
resetButton.addActionListener(this);
ionumokButton=newButton("确定");
ionumokButton.setBackground(Color.green);
ionumokButton.setBounds(200,610,50,25);
ionumokButton.addActionListener(this);
processSetButton=newButton("设置");
processSetButton.setBackground(Color.green);
processSetButton.setBounds(480,610,50,25);
processSetButton.addActionListener(this);
startButton=newButton("开始");
startButton.setBounds(1270,540,50,25);
startButton.setBackground(Color.green);
startButton.addActionListener(this);
suspendButton=newButton("暂停");
suspendButton.setBounds(1270,575,50,25);
suspendButton.setBackground(Color.green);
suspendButton.addActionListener(this);
continueButton=newButton("继续");
continueButton.setBounds(1270,610,50,25);
continueButton.setBackground(Color.green);
continueButton.addActionListener(this);
datainputButton=newButton("导入数据");
datainputButton.setBounds(480,540,50,25);
datainputButton.addActionListener(this);
procountField=newTextField();
procountField.setBounds(120,610,50,25);
procountField.addActionListener(this);