操作系统课程设计Spooling假脱机输入输出模拟附源程序.docx
- 文档编号:16339465
- 上传时间:2023-07-12
- 格式:DOCX
- 页数:23
- 大小:333.41KB
操作系统课程设计Spooling假脱机输入输出模拟附源程序.docx
《操作系统课程设计Spooling假脱机输入输出模拟附源程序.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计Spooling假脱机输入输出模拟附源程序.docx(23页珍藏版)》请在冰点文库上搜索。
操作系统课程设计Spooling假脱机输入输出模拟附源程序
一、需求分析
设计一个SP00LING输出进程和两个请求输出的用户进程,以及一个SP00LING输出服务程序。
当请求输出的用户进程希望输出一系列信息时,调用输出服务程序,由输出服务程序将该信息送入输出井。
待遇到一个输出结束标志时,表示进程该次的输出文件输出结束。
之后,申请一个输出请求块(用来记录请求输出的用户进程的名字、信息在输出井中的位置、要输出信息的长度等),等待SP00LING进程进行输出。
SP00LING输出进程工作时,根据请求块记录的各进程要输出的信息,把信息输出到文本框里。
进程调度采用随机算法,这与进程输出信息的随机性相一致。
两个请求输出的用户进程的调度概率各为45%,SP00LING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。
编码实现的平台环境是JCreator4.50Pro,实现语言是Java。
为每个进程建立一个pcb,记录进程信息,进程有5种状态:
0为可执行态;
1为等待状态1,表示输出井满,请求输出的用户进程等待;
2为等待状态2,表示请求输出井空,SP00LING输出进程等待;
3为等待状态3,表示请求输出井满,请求输出的用户进程等待;
4为结束态,进程执行完成。
二、整体功能及设计
1、数据结构:
1)进程控制块PCB
classPcb{
intid;进程标识数
intstatus;进程状态
intcount;要输出的文件数
intx;进程输出时的临时变量
}
2)请求输出块Reqblock
classReqblock{
intrepname;请求进程名
intlength;本次输出信息长度
intaddr;信息在输出井的首地址
}
3)输出井BUFFER
intbuffer[3][100]
buffer[1][100]为用户进程1的输出井,buffer[2][100]为用户进程2的输出井
4)其他主要的控制变量和指针
intc1[3];c1[1]为输出井buffer[1]的空间,c1[2]为输出井buffer[2]的空间
intc2[3][2];c2[1][0]、c2[2][0]为输出井buffer[i]第一个空闲指针
c2[1][1]、c2[2][1]为输出井buffer[i]第一个满指针
intc3;reqblock的剩余个数
intpt1;要输出的第一个reqblock指针
intpt2;第一个空闲reqblock指针
2、主要类及其函数
1)主类publicclassSpooling
publicSpooling():
构造函数,生成界面,为按钮添加事件监听器
publicvoidactionPerformed(ActionEvente):
单击事件响应函数
publicvoidbegin():
点击"重置"按钮时,重新初始化界面
publicvoidrun():
点击运行时,转入调度函数
publicstaticvoidmain(Stringargs[]):
生成Spooling类的对象
2)调度实施类classManage
publicManage(Spoolingspooling1):
构造函数,对进程的数据初始化
publicvoidrun():
SP00LING输出模拟系统主控函数,用随机数来决定调度的进程,使得两个请求输出的用户进程的调度概率各为45%,SP00LING输出进程为10%。
publicintuser(intname,intout,JTextAreatextarea,JTextFieldfield):
SP00LING输出服务程序,当请求输出的用户进程希望输出一系列信息时,通过传参调用输出服务程序,由输出服务程序将该信息送入输出井。
publicvoidspooling1():
SPOOLING输出进程,根据请求块记录的各进程要输出的信息,把信息输出到文本框里。
3、流程图
(1)SP00LING输出模拟系统主控流程图如图1所示。
图1SP00LING输出模拟系统主控流程图
(2)SP00LING输出服务程序流程图如图2所示。
图2输出请求服务的程序框图
(3)SPOOLING输出进程流程图如图3所示。
图3SP00LING输出进程流程图
三、编程实现
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
importjava.lang.Math;
importjava.util.Random;
/*1)主类publicclassSpooling
publicSpooling():
构造函数,生成界面,为按钮添加事件监听器
publicvoidactionPerformed(ActionEvente):
单击事件响应函数
publicvoidbegin():
点击"重置"按钮时,重新初始化界面
publicvoidrun():
点击运行时,转入调度函数
publicstaticvoidmain(Stringargs[]):
生成Spooling类的对象*/
publicclassSpoolingextendsJFrameimplementsActionListener,Runnable{
JPanelpanel1,panel2,panel3;
JTextFieldfield1,field2;
JScrollPanep1,p2,p3,p4;
JTextAreatextarea1,textarea2,textarea3,textarea4;
JButtonbutton1,button2,button3;
Managespoo;
publicSpooling()//界面构造函数
{
spoo=newManage(this);
Containerc=this.getContentPane();
c.setLayout(newBorderLayout());
field1=newJTextField(3);//设置panel1
field2=newJTextField(3);
button1=newJButton("运行");
button2=newJButton("关闭");
button3=newJButton("重置");
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
panel1=newJPanel();
panel1.setLayout(newFlowLayout());
panel1.add(newJLabel("用户进程1文件数:
",SwingConstants.RIGHT));
panel1.add(field1);
panel1.add(newJLabel("用户进程2文件数:
",SwingConstants.RIGHT));
panel1.add(field2);
panel1.add(button1);
panel1.add(button3);
panel1.add(button2);//设置panel1完毕
textarea1=newJTextArea(80,100);//设置panel2
textarea2=newJTextArea(112,400);
textarea3=newJTextArea(112,400);
textarea1.append("用户进程1的输出\n");
textarea2.append("用户进程2的输出\n");
textarea3.append("Spooling的调度\n");
p1=newJScrollPane(textarea3);
p2=newJScrollPane(textarea1);
p3=newJScrollPane(textarea2);
panel2=newJPanel();
panel2.setLayout(newGridLayout(1,3));
panel2.add(p1);
panel2.add(p2);
panel2.add(p3);//设置panel2完毕
textarea4=newJTextArea(10,150);//设置panel3
textarea4.append("主程序调度过程\n");
p4=newJScrollPane(textarea4);
panel3=newJPanel();
panel3.setLayout(newGridLayout(1,1));
panel3.add(p4);//设置panel3完毕
c.add(panel1,BorderLayout.NORTH);//设置窗口
c.add(panel2,BorderLayout.CENTER);
c.add(panel3,BorderLayout.SOUTH);
this.setSize(1200,600);
this.setLocation(100,100);
this.setTitle("Spooling");
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口完毕
}
publicvoidactionPerformed(ActionEvente)
{
if(e.getSource()==button1)//点击运行按钮,run()
{
run();
}
if(e.getSource()==button2)//点击重置按钮,begin()
{
System.exit(0);
}
if(e.getSource()==button3)//点击推出按钮,退出
{
begin();
}
}
publicvoidbegin()
{
field1.setText("");//点击重置,重新初始化界面
field2.setText("");
textarea1.setText("用户进程1的输出\n");
textarea2.setText("用户进程2的输出\n");
textarea3.setText("Spooling的调度\n");
textarea4.setText("主程序调度过程\n");
}
publicvoidrun()//点击运行时,转入调度函数
{
spoo.start();
}
publicstaticvoidmain(Stringargs[])
{
Spoolingspooling=newSpooling();
}
}
/*2)调度实施类classManage
publicManage(Spoolingspooling1):
构造函数,对进程的数据初始化
publicvoidrun():
SP00LING输出模拟系统主控函数,用随机数来决定调度的进程,使得两个请求输出的用户进程的调度概率各为45%,SP00LING输出进程为10%。
publicintuser(intname,intout,JTextAreatextarea,JTextFieldfield):
SP00LING输出服务程序,当请求输出的用户进程希望输出一系列信息时,通过传参调用输出服务程序,由输出服务程序将该信息送入输出井。
publicvoidspooling1():
SPOOLING输出进程,根据请求块记录的各进程要输出的信息,把信息输出到文本框里。
*/
classManageextendsThread{
Pcbpcb[];
Reqblockreqblock[];
intbuffer[][];
intc1[];//可使用的输出井buffer空间
intc2[][];//输出井buffer空闲和满指针
intc3;//reqblock的剩余个数
intpt1;//要输出的第一个reqblock指针
intpt2;//第一个空闲reqblock指针
doublerandom;//用于调度三个进程的控制随机数
intout1;//用户进程1已生成的文件数
intout2;//用户进程2已生成的文件数
intout_1;//用户进程1已输出的文件数
intout_2;//用户进程2已输出的文件数
intx;//随机生成的数据0~9
inti;//临时控制变量
Randomx1;//辅助生成随机数据x:
0~9
Spoolingspooling;
publicManage(Spoolingspooling1){//对各进程的数据初始化
out1=0;out2=0;
out_1=0;out_2=0;
pcb=newPcb[4];
reqblock=newReqblock[10];
buffer=newint[3][100];
c1=newint[3];
c1[1]=100;c1[2]=100;
c2=newint[3][2];
c2[1][0]=0;
c2[2][0]=0;
c3=10;
pt1=0;
pt2=0;
x1=newRandom();
for(i=0;i<4;i++)
{
pcb[i]=newPcb();
}
for(i=0;i<10;i++)
{
reqblock[i]=newReqblock();
}
for(i=1;i<=3;i++)
{
pcb[i].status=0;
}
spooling=spooling1;//对各进程的数据初始化完毕
}
publicvoidrun()//进程调度
{
do//while循环
{
random=Math.random();//产生一个随机数,控制进程调度,令用户进程概率为45%,Spooling进程为10%
if(random<=0.45&&pcb[1].status==0)//调度用户进程1
{
spooling.textarea4.append("调度用户进程1\n");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
out1=user(1,out1,spooling.textarea1,spooling.field1);
}
elseif(random>0.45&&random<=0.9&&pcb[2].status==0)//调度用户进程2
{
spooling.textarea4.append("调度用户进程2\n");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
out2=user(2,out2,spooling.textarea2,spooling.field2);
}
elseif(random>=0.9&&random<1&&pcb[3].status==0)//调度spooling进程
{
spooling.textarea4.append("调度Spooling进程\n");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
spooling1();
}
}
while(pcb[1].status!
=4||pcb[2].status!
=4||pcb[3].status!
=4);//while结束
spooling.textarea4.append("程序运行完毕\n");//进程调度结束
}
publicintuser(intname,intout,JTextAreatextarea,JTextFieldfield)//用户进程
{
pcb[name].id=name;
pcb[name].count=Integer.parseInt(field.getText());
while(out!
=pcb[name].count)//判断进程所要输出的文件是否输出完毕的while循环
{
c2[name][1]=c2[name][0];
do//判断进程的一个文件是否输出完毕的while循环
{
x=x1.nextInt(9);//x为每次随机生成的数据0~9,送入pcb.x
pcb[name].x=x;
if(c1[name]==0)//若输出井buffer满,变为等待状态1,转调度程序
{
pcb[name].status=1;
if(c2[name][0]>=c2[name][1])
c1[name]=c1[name]+c2[name][0]-c2[name][1];
else
c1[name]=c1[name]+100-c2[name][1]+c2[name][0];
c2[name][0]=c2[name][1];
textarea.append("第"+(out+1)+"个文件缺少输出井,");
textarea.append("进入等待状态1\n");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
returnout;
}
else//若输出井没满
{
buffer[name][c2[name][0]]=pcb[name].x;//进程的输出信息PCB[i].x送buffer[i][C2[i][0]]
c1[name]=c1[name]-1;//输出井空闲个数减1
c2[name][0]=(c2[name][0]+1)%100;//修改空缓冲区指针C2[i][0]前进1
}
}while(x!
=0);//判断进程的一个文件是否输出完毕的while循环结束
textarea.append("第"+(out+1)+"个文件已放入输出井:
"+c2[name][1]+"~"+(c2[name][0]-1)+"剩余空间"+c1[name]+"。
");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
out++;
if(c3==0)//若没有空闲请求输出块,转为等待状态3
{
pcb[name].status=3;
if(c2[name][0]>=c2[name][1])
c1[name]=c1[name]+c2[name][0]-c2[name][1];
else
c1[name]=c1[name]+100-c2[name][1]+c2[name][0];
c2[name][0]=c2[name][1];
out--;
textarea.append("缺少请求输出块,");
textarea.append("进入等待状态3。
\n");
try{
sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
out++;
returnout;
}
else//若有空闲请求输出块
{
reqblock[pt2].addr=c2[name][1];//将文件在输出井的位置填入空闲请求块
if(c2[name][0]>=c2[name][1])//将文件在输出井的长度填入空闲请求块
reqblock[pt2].length=c2[name][0]-c2[name][1];
else
reqblock[pt2].length=100-c2[name][1]+c2[name][0];
reqblock[pt2].repname=name;//将进程名i填入请求块
textarea.append("获得请求输出块"+(Integer.toString(pt2+1))+"\n");
pt2=(pt2+1)%10;//修改空闲请求块指针
c3--;//空闲请求块数减1
if(pcb[3].status==2)//若SPOOLING进程是等待状态,则唤醒SPOOLING进程
{
pcb[3].status=0;
}
}
}//判断进程所要输出的文件是否输出完毕的while循环结束
textarea.append("进程"+name+"输出完毕!
");//文件输出完毕,修改状态为结束,转进程调度
pcb[name].status=4;
r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 课程设计 Spooling 脱机 输入输出 模拟 源程序