操作系统课程设计报告书.docx
《操作系统课程设计报告书.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计报告书.docx(11页珍藏版)》请在冰豆网上搜索。
![操作系统课程设计报告书.docx](https://file1.bdocx.com/fileroot1/2022-11/30/f2632ae8-16cc-4c95-afbc-1d5d6681980e/f2632ae8-16cc-4c95-afbc-1d5d6681980e1.gif)
操作系统课程设计报告书
课程设计报告
(2011--2012年度第二学期)
课程名称:
操作系统实验
课设题目:
SPOOLING假脱机输入输出技术模拟
院系:
控制与计算机工程学院
班级:
软件1002
姓名:
王怡
指导教师:
贾静平
设计周数:
一周
成绩:
2012年6月27日
∙需求分析
SPOOLING技术实质上是用户进程利用一个共享设备的一个存储区,并不是真正占有这一设备,用户进程把要完成的任务以文件的形式存入存储区,在存储区中排队并等待SPOOLING系统调度,只有被SPOOLING系统调度并输出,此项任务才真正完成,通过SPOOLING技术可以使独占设备成为共享设备,由此大大提高了设备的使用率,节约了硬件资源。
∙整体功能及设计
1.整体功能
SPOOLING系统由专门负责I/O的常驻内存的进程以及输入井、输出井组成;它将独占设备改造为共享设备,实现了虚拟设备功能。
将一台独享打印机改造为可供多个用户共享的打印机,是应用SPOOLING技术的典型实例。
具体做法是:
系统对于用户的打印输出,但并不真正把打印机分配给该用户进程,而是先在输出井中申请一个空闲盘块区,并将要打印的数据送入其中;然后为用户申请并填写请求打印表,将该表挂到请求打印队列上。
若打印机空闲,输出程序从请求打印队首取表,将要打印的数据从输出井传送到内存缓冲区,再进行打印,直到打印队列为空。
2.设计思想
本次课程设计采用进程的随机调度法模拟Spooling,一共有2个用户进程和一个SPOOLING进程。
其中有45%的概率调度用户进程1,45%的概率调度用户进程2,10%的概率调度SPOOLING进程。
进程基本状态有3种,分别为可执行,等待和结束。
可执行态就是进程正在运行或等待调度的状态;等待状态又分为等待状态1,等待状态2,等待状态3。
状态变化的条件为:
1>进程执行完成时,置为“结束”态。
2>服务程序在将输出信息送输出井时,如发现输出井已满,将调用进程置为“等待状态1”。
3>SPOOLING进程在进行输出时,若输出井空,则进入“等待状态2”。
4>SPOOLING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。
5>服务程序在输出信息到输出井并形成输出请求信息块后,若SPOOLING进程处于等待态则将其置为“可执行状态”。
6>当用户进程申请请求输出块时,若没有可用请求块时,调用进程进入“等待状态3”。
3.程序框图
(1)SP00LING输出模拟系统主控流程图如图1所示。
图1SP00LING输出模拟系统主控流程图
(2)SP00LING输出服务程序由请求输出的两个用户进程调用,程序流程图如图2所示。
图2输出请求服务的程序框图
(3)SPOOLING输出进程流程图如图3所示。
图3SP00LING输出进程流程图
∙编程实现
在本次课程设计中,程序的主要功能的实现一共使用了3个类。
∙PCB类:
ClassCPcb
{
public:
intm_id;//进程标识id
intm_status;//进程状态
intm_count;//要输出的文件个数
intm_x;//进程在输出时的临时变量
}
∙Repblock类:
ClassCRepblock
{
public:
intm_reqname;//请求进程id
intm_length;//本次输出长度
intm_addr;//信息在输出井的首地址
}
∙SPLDlg对话框类:
ClassCSPLDlg
{
Public:
CPcbpcb[3];//三个进程,其中pcb[0]、pcb[1]为用户进程,pcb[2]为输出进程
CReqBlockreq[10];//用户请求输出块
intbuffer[2][100];//用户输出井
intc1[2];//用户输出井剩余大小
intc2[2][2];//输出井使用情况
intc3;//请求输出块剩余大小
intptr1;//请求输出块使用情况
intptr2;
voidinit();//初始化个数据块
voidprint();//打印请求数据块内容
voidDispatchUser(intid);//输出请求服务的程序
voidDispatchSpooling();//SP00LING输出进程
}
∙核心函数:
voidCSPLDlg:
:
DispatchUser(intid)
{
intx=1;
intcount=0;
if(pcb[id].m_status==0)
{
while(pcb[id].m_count>0)
{
x=rand()%10;
while(x)
{
if(c1[id]>0)//第一个输出井不满
{
buffer[id][c2[id][1]]=x;
c2[id][1]=(c2[id][1]++)%100;
c1[id]--;
count++;
x=rand()%10;
}
else
{
pcb[id].m_status=1;//等待
return;
}
}
pcb[id].m_count--;
if(c3>0)//请求控制块不为满
{
req[ptr2].m_reqname=id;//第一个进程
req[ptr2].m_length=count;
req[ptr2].m_addr=c2[id][0];//输出井的起始位置
c3--;
ptr2=(ptr2++)%10;
c2[id][0]=c2[id][1];
if(pcb[2].m_status==2)
{
pcb[2].m_status=0;
return;
}
return;
}
else
{
pcb[id].m_status=3;
return;
}
}
}
}
Spooling进程调度函数:
voidCSPLDlg:
:
DispatchSpooling()
{
if(pcb[2].m_status==0)
{
if(c3!
=10)
{
if(req[ptr1].m_length>0)
print();
if(pcb[0].m_status==1||pcb[1].m_status==1)
{
if(pcb[0].m_status==1)
{
pcb[0].m_status=0;
}
elseif(pcb[1].m_status==1)
{
pcb[1].m_status=0;
}
return;
}
else
{
ptr1=(ptr1++)%10;
c3++;
if(pcb[0].m_status==3||pcb[1].m_status==3)
{
if(pcb[0].m_status==3)
{
pcb[0].m_status=0;
}
elseif(pcb[1].m_status==3)
{
pcb[1].m_status=0;
}
return;
}
}
}
else
{
if(pcb[0].m_count==0&&pcb[0].m_count==0)
{
pcb[2].m_status=4;
return;
}
else
pcb[2].m_status=2;
}
}
}
∙使用说明
图4主界面
如图4所示:
输入完第一个和第二个进程打印的文件个数后打击打印按钮,即可显示文件的打印顺序。
∙结果分析
图5结果分析图
图6结果分析图
当用户输出第一个用户进程和第二个用户进程的文件数量分别为3和2时,程序随机调度进程并为每一个文件产生内容,从图5的打印序列可以看出,程序首先调度用户进程2,直到用户进程2的三个文件都送到输出井。
然后调用用户进程1,将用户进程1的三个文件送入输入井。
Spooling进程可能在两个用户进程间调用,也可能在进程1调用完之后调用。