操作系统课程设计之独占设备的分配.docx
《操作系统课程设计之独占设备的分配.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计之独占设备的分配.docx(29页珍藏版)》请在冰豆网上搜索。
操作系统课程设计之独占设备的分配
操作系统课程设计报告
院(系):
专业:
学生姓名:
班级:
学号:
题目:
独占设备的分配与回收
起迄日期:
设计地点:
实验中心
指导教师:
2011—2012年度第2学期
完成日期:
2012年7月10日
一、课程设计目的
在多到程序环境下,系统中的设备供所有进程共享。
为防止进程对系统资源的无序竞争,特规定系统设备不允许用户自行使用,必须由系统统一分配。
每当进程项系统提出I/O请求时,只要是可能和安全带,设备分配程序编按照一定的策略,吧设备分配给请求用户。
在有的系统中,为了确保在CPU与设备之间能进行通信,还应分配相应的控制器和通道。
为了实现设备分配,必须在系统中设置相应的数据结构。
掌握独占设备的分配流程,会使用安全性算法检查设备分配是否安全
二、课程设计内容与要求
1)合理设计SDT、DCT、COCT、CHCT的数据结构
2)独占设备、控制器与通道的数目可在界面进行设置
3)进程申请使用独占设备时至少要求包括申请时间与使用时间
4)可读取样例数据(要求存放在外部文件中)进行独占设备、控制器与通道数目的初始化,进行进程申请设备的初始化
5)点击开始运行后,系统自动根据初始设定的数据进行设备分配与回收,所有状态信息需动态地显示出来:
设备、控制器、通道数目,阻塞队列情况等
6)运行中可动态增加申请设备的进程,可随时暂停,查看当前状态
7)使用可视化界面进行演示
三、系统分析与设计
1、系统分析
(1)信息:
此系统中包括了SDT、DCT、COCT、CHCT表,其中SDT包括了设备的类型,设备标识符;DCT包括设备类型、设备标识符、设备状态、该设备指向的控制器;COCT包括控制器标识符、控制器状态、与控制器相连的通道;CHCT包括通道标识符、通道状态、与通道相连的控制器。
(2)行为:
某进程在某时间申请某设备,系统通过查看申请设备的状态和控制器、通道来判断该进程能否申请成功、是否阻塞等并动态的显示出进程申请的时间和使用时间等信息。
(3)表示:
系统包括3个界面:
主界面、申请进程界面和添加设备界面。
主界面包含了初始化按钮、开始按钮、添加设备、申请新进程、暂停按钮。
其中添加设备和申请新进程按钮分别于添加设备界面和申请进程界面接口。
申请进程界面需要输入新进程名,申请设备的类型、标识符和进程开始时间和执行时间;添加设备界面需要输入设备的类型、标识符、控制器和通道。
2、系统设计:
2.1、模块设计:
次程序包括3个包,分别为table包、map包、jframe包。
table包中有SDT、DCT、COCT、CHCT表的结构;map包包括了分别对应SDT、DCT、COCT、CHCT的表的映射的写入和读的方法;jframe包包括界面和主要函数(MainF类、Mythread类、increase类、increaseP类、Fileread类)。
MainF类能调用Mythread类、Fileread类,申请进程界面调用increaseP类,添加设备界面调用increase类
2.2、数据结构说明:
设计中用到了Map(映射)的数据结构,Map结构包括了key和value两部分,通过key的匹配来查询value的值,符合次涉及到的要求,解决了四张表之间的关系
publicstaticMapmapD=newHashMap();
//对应DCT表的映射,key值为设备类型
publicstaticMapmapS=newHashMap();
//对用SDT的映射,key值为设备类型
publicstaticMapmapCO=newHashMap();
//对应COCT的映射,key值为控制器标识符
publicstaticMapmapCH=newHashMap();
//对应CHCT的映射,key值为通道标识符
publicstaticMythread[]mt=newMythread[3];
//允许申请3个进程,可根据需要做相应更改
以上4个映射用于存放对应表的信息,设计为全局静态是为了能存储文件和添加的设备、控制器、通道信息。
2.3、算法流程图:
实现设计中主程序和其他子模块的算法,以流程图的形式表示,需画出函数和过程的调用关系图。
文件读取Fileread(初始化)类
添加设备increase类
申请新进程increaseP类
Mythread类:
进程执行的方法
MainF类
四、系统测试与调试分析
1、系统测试
●测试方法:
黑盒
●测试技术:
功能测试
●测试数据:
包括正确的输入及其输出结果和含有错误的输入及其输出结果。
●测试报告:
必须包含最终测试结果:
列出你的测试结果,包括输入和输出。
这里的测试数据应该完整和严格。
功能测试应用背景:
它是从使用者的角度来编写的,它关注系统提供的功能特征及其不同的处理条件;测试功能的不同处理流程(包括正常处理的和异常处理);一个功能测试用例仅用于测试一个功能,一个功能可能需要多个功能测试用例来覆盖。
测试说明
测试名称
独占设备的分配与回收
测试目的
验证系统初始化的成功与否
测试技术
功能测试
测试方法
黑盒测试法
测试用例
测试内容
从指定文件读入所需信息并显示
测试步骤
从正确文件读入正确格式的信息
从正确的文件读入错误的信息
从错误的文件读入错误的信息
测试数据
f:
//aa.txt读格式正确的信息
f:
//aa.txt读格式错误的信息
从f:
//b.txt读格式错误信息
预期结果
正常显示
系统提示错误
系统提示错误
测试结果
与预期相符
与预期相符
与预期相符
测试说明
测试名称
独占设备的分配与回收
测试目的
验证进程申请资源的成功与否
测试技术
功能测试
测试方法
黑盒测试法
测试用例
测试内容
进程申请设备并显示信息
测试步骤
不同进程申请不同资源
不同的进程申请相同的资源
进程申请不存在的设备
测试数据
process1申请print资源
process2申请keyword资源
process3申请io资源
process1、process2、process3申请print资源
Process1申请xxx资源
预期结果
各进程单独执行显示
根据先来先服务申请释放资源并显示
显示没有该设备
测试结果
与预期相符
与预期相符
与预期相符
测试说明
测试名称
独占设备的分配与回收
测试目的
验证暂停功能能否实现
测试技术
功能测试
测试方法
黑盒测试法
测试用例
测试内容
点击暂停按钮看MainF信息是否暂停更新
测试步骤
点击暂停按钮观察信息
不点击暂停按钮观察信息
测试数据
Process1申请print资源的信息动态显示为“阻塞中……”
Process1申请print资源的信息动态显示为“阻塞中……”
预期结果
信息不改变
信息更新为其他信息
测试结果
与预期相符
与预期相符
2、调试分析:
文件读入是系统报错是因为读入的格式错误或文件的某一行没有数据导致,因此在这严格限制了初始化文件的格式;在将设备信息和进程信息存储到相应的数据结构中时,发生了信息覆盖的问题,这是因为没有在每读一行的时候都新建了新的进程Mythread和4张表;在进程执行的时候当发现没有要申请的设备时会报错,因此用trycatch语句将错误信息遮蔽。
编程中的难点在于如何动态显示信息内容,尤其是发生阻塞时不好控制,“暂停”按钮的实现也比较难,现在只能让系统暂停一定的时间无法根据用户的意志进行暂停和继续,对进程的知识储备还不够。
五、用户手册
1、使用平台:
Myeclipse8.6;下载网址:
2、不需要安装
3、程序使用手册
(1)主窗口
(2)有两种选项:
初始化或添加设备和申请进程
初始化
点击开始,程序运行
点击暂停可使系统暂停之心30s
添加新设备
申请新进程(申请的设备存在)
申请进程(申请的设备不存在)
六、程序清单
列出主要/关键算法的程序清单,要求加上详细的程序注释(函数体/过程注释,与语句行注释)
packagejframe;
importjava.io.BufferedReader;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importmap.CHCTmap;
importmap.COCTmap;
importmap.DCTmap;
importmap.SDTmap;
importtable.CHCT;
importtable.COCT;
importtable.DCT;
importtable.SDT;
/*文件读取代码
*
*/
publicclassFileread{
Stringfile="f:
//aa.txt";//文件的地址
Stringnext=null;//用来存放文件每行的信息
String[]s=newString[7];//将next值按空格分开后存到S数组中
SDTmapsm=newSDTmap();
DCTmapdm=newDCTmap();
COCTmapcom=newCOCTmap();
CHCTmapchm=newCHCTmap();
MainFmf=newMainF();
publicFileread(){}
publicFileread(inti)throwsNumberFormatException,IOException{
try{
BufferedReaderinput=newBufferedReader(newInputStreamReader(newFileInputStream(file)));//读文件
while((next=input.readLine())!
=null){
Mythreadmyt=newMythread();
SDTsdt=newSDT();
DCTdct=newDCT();
COCTcoct=newCOCT();
CHCTchct=newCHCT();
s=next.split("");
sdt.settypeS(s[0]);
sdt.setdeS(s[1]);
dct.set(s[0],s[1],s[2]);
coct.set(s[2],s[3]);
chct.set(s[3],s[2]);
myt.set(s[4],s[0],s[1],Double.valueOf(s[5]),Double.valueOf(s[6]));
mf.mt[mf.ii++]=myt;
sm.setmapS(s[0],sdt);
dm.setmapD(s[0],dct);
com.setmapCO(s[2],coct);
chm.setmapCH(s[3],chct);
//将读到的信息写入4张表对应的映射和进程数组中
}
}catch(FileNotFoundExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
//添加设备的代码
Stringstr1=jTextField1.getText();//获得jTextField1中的信息
Stringstr2=jTextField2.getText();
Stringstr3=jTextField3.getText();
Stringstr4=jTextField4.getText();
SDTsdt=newSDT();
DCTdct=newDCT();
COCTcoct=newCOCT();
CHCTchct=newCHCT();
sdt.settypeS(str1);
sdt.setdeS(str2);
dct.set(str1,str2,str3);
coct.set(str3,str4);
chct.set(str4,str3);
MainF.mapS.put(str1,sdt);
MainF.mapD.put(str1,dct);
MainF.mapCO.put(str3,coct);
MainF.mapCH.put(str4,chct);
this.dispose();//当前的窗口关闭
//申请新进程代码
Stringstr1=jTextField1.getText();
Stringstr2=jTextField2.getText();
Stringstr3=jTextField3.getText();
Stringstr4=jTextField4.getText();
Stringstr5=jTextField5.getText();
doubled1=Double.valueOf(str4);
doubled2=Double.valueOf(str5);
Mythreadmtt=newMythread();
mtt.set(str1,str2,str3,d1,d2);
MainF.mt[MainF.ii++]=mtt;
this.dispose();
//进程代码
packagejframe;
importjava.io.IOException;
importjava.util.Iterator;
importjava.util.Map;
importjavax.swing.JTextArea;
importtable.CHCT;
importtable.COCT;
importtable.DCT;
importmap.CHCTmap;
importmap.COCTmap;
importmap.DCTmap;
importmap.SDTmap;
publicclassMythreadextendsThread{
SDTmapsm=newSDTmap();
Stringcon=null;//用来记录当前进程申请设备的控制器
Stringch=null;//用来记录当前进程申请设备的通道
DCTdct=newDCT();
COCTcoct=newCOCT();
CHCTchct=newCHCT();
Filereadfilr=newFileread();
Stringname;//记录进程名
doublestarttime,runtime;//记录进程的开始时间(会变)和执行时间
doubletime,use;//time用来记录进程的起始时间,use记录使用时间
Stringapptype;//记录进程要申请的设备类型
Stringappde;//设备标识符
Stringss="";//记录jtextArea要显示的信息
JTextAreatext;
publicvoidset(Stringname,Stringapptype,Stringappde,doublestarttime,doubleruntime){
this.name=name;
this.apptype=apptype;
this.appde=appde;
this.starttime=starttime;
this.runtime=runtime;
}
publicvoidJT(JTextAreatext){
this.text=text;
}
publicvoidsettime(doubletime){
this.time=time;
}
publicvoidsetut(doubled){
this.use=d;
}
publicvoidrun(){
//判断要申请的设备是否存在,不存在进程沉睡999.999s
try{
dct=(DCT)filr.dm.getmapD().get(apptype);
con=dct.get();
coct=(COCT).getmapCO().get(con);
ch=coct.get();
}catch(Exceptione){
text.setText("无该类设备");
try{
Thread.sleep(999999);
}catch(InterruptedExceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
}
try{
Thread.sleep((long)time*1000);//进程在开始前睡眠
if(MainF.signal==1){//signal为暂停标识符,为1是暂停30s
Thread.sleep(30000);
MainF.signal=0;
}
text.setText("阻塞中....");
Thread.sleep((long)(starttime-time)*1000);//阻塞时间
if(MainF.signal==1){
Thread.sleep(30000);
MainF.signal=0;
}
ss="进程"+name+"向"+"设备"+apptype+""+appde+"提出申请"+"\n"+"通过控制器:
"+con+"通道:
"+ch+"\n"
+"开始执行时间:
"+starttime+"\t"+"执行中.....";
text.setText(ss);//jtextArea显示ss的信息
Thread.sleep((long)runtime*1000);//睡眠执行时间
if(MainF.signal==1){
Thread.sleep(30000);
MainF.signal=0;
}
ss="执行结束,使用时间"+use+""+"释放资源";
text.setText(ss);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
publicStringgetname(){
returnname;
}
}
//主界面开始函数
inti=0;
intj=0;
intk=ii;//ii为全局静态变量,存储申请的进程数目
Mythreadmyt=null;
//冒泡排序,按开始时间升序排序进程
if(k>=2){
for(i=0;ifor(j=i+1;jif(mt[i].starttime>mt[j].starttime){
myt=mt[i];
mt[i]=mt[j];
mt[j]=myt;
}
}
}
}
//根据不同的进程数使用不同的方法
switch(ii){
case1:
jTextArea2.setText("该进程未使用");
mt[0].settime(mt[0].starttime);
mt[0].setut(mt[0].runtime);
mt[0].JT(jTextArea2);
mt[0].start();
jTextArea3.setText("该进程未使用");
jTextArea4.setText("该进程未使用");
break;
case2:
jTextArea2.setText("该进程未使用");
jTextArea3.setText("该进程未使用");
jTextArea4.setText("该进程未使用");
mt[0].settime(mt[0].starttime);
mt[1].settime(mt[1].starttime);
mt[0].setut(mt[0].runtime);
mt[0].JT(jTextArea2);
mt[0].start();
//判断是否阻塞,阻塞之后的方法
if(mt[0].apptype.equals(mt[1].apptype)){
if((mt[0].starttime+mt[0].runtime)>mt[1].starttime){
mt[1].starttime=mt[0].starttime+mt[0].runtime;
mt[1].setut(mt[1].starttime+mt[1].runtime-mt[1].time);
mt[1].JT(jTextArea3);
mt[1].start();
}
}else{
mt[1].setut(mt[1].runtime);
mt[1].JT(jTextArea3);
mt[1].start();
}
break;
case3:
jTextArea2.setText("该进程未使用");
jTextArea3.setText("该进程未使用");
jTextArea4.setText("该进程未使用");
mt[0].settime(mt[0].starttime);
mt[1].settime(mt[1].starttime);
mt[