SPOOLing技术模拟实现说明书Word格式文档下载.docx
《SPOOLing技术模拟实现说明书Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《SPOOLing技术模拟实现说明书Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。
若系统的某台台行式打印机采用了虚拟设备技术,那么若有进程要求对它打印输出时,SPOOLING系统并不是将这台打印机直接分配给进程,而是在共享设备(磁盘或磁鼓)上的输出SPOOLING存储区中为其分配一块存储空间,进程的输出数据以文件形式此。
各进程的数据输出文件形成了一个输出队列,由输出SPOOLING系统控制这台打印机进程,依次将队列中的输出文件实际打印输出。
在SPOOLING系统中,实际上并没有为任何进程分配,而只是在输入井和输出井中,为进程分配一存储区和建立一章I/O请求表。
这样,便把独占设备改造为共享设备。
文档为个人收集整理,来源于网络本文为互联网收集,请勿用作商业用途
宏观上,虽然是多个进程在同时使用一台独立设备,而对每一个进程而言,它们都认为自己是独占了一个设备.当然,该设备只是逻辑上的设备SPOOLING系统实现了将独占设备变换为若干台对应的逻辑设备的功能。
操作系统初启后激活SPOOLING输入程序使它处于捕获输入请求的状态,一旦有输入请求消息,SPOOLING输入程序立即得到执行,把装在输入设备上的作业输入到硬盘的输入井中。
输入井是一组硬盘扇区SPOOLING输出把硬盘上输出井的数据送到慢速的输出设备上.输出井的数据来自作业运行过程中的输出。
这就是说,作业调度程序不是从输入设备上装入作业,而是直接从输入井中把选中的作业装入主存,使主机等待作业输入的时间大为缩短.同样对作业的输出而言,写到输出井要比写到输出设备快得多。
即使作业的JCB(作业进程块)已注销,SPOOLING输出活动仍可以从容地把输出井中没有输出完的数据继续输出到输出设备上。
由此可见,引入SPOOLING技术,把一个共享的硬盘改造成若干台输入设备(对作业调度程序而言)和若干台输出设备(对各作业而言)。
这样的设备称为虚拟设备,它们的物理实体是输入(出)井.这样改造之后,保持了物理的输入(出)设备繁忙地与主机并行地工作,提高了整个系统的利用率。
SPOOLING技术是在通道技术和多道程序设计基础上产生的,它由主机和相应的通道共同承担作业的输入输出工作,利用磁盘作为后援存储器,实现外围设备同时联机操作.
SPOOLING系统由专门负责I/O的常驻内存的进程以及输入井、输出井组成;
它将独占设备改造为共享设备,实现了虚拟设备功能。
将一台独享打印机改造为可供多个用户共享的打印机,是应用SPOOLING技术的典型实例。
具体做法是:
系统对于用户的打印输出,但并不真正把打印机分配给该用户进程,而是先在输出井中申请一个空闲盘块区,并将要打印的数据送入其中;
然后为用户申请并填写请求打印表,将该表挂到请求打印队列上。
若打印机空闲,输出程序从请求打印队首取表,将要打印的数据从输出井传送到内存缓冲区,再进行打印,直到打印队列为空。
SPOOLING技术实现设备管理时的工作特征:
1、提高了I/O速度.
2、将独占设备改造为共享设备。
在SPOOLING系统中,实际上并没有为任何进程分配,而只是在输入井和输出井中,为进程分配一存储区并建立一张I/O请求表。
宏观上,虽然是多个进程在同时使用一台独立设备,而对每一个进程而言,它们都认为自己是独占了一个设备。
当然,该设备只是逻辑上的设备。
SPOOLING系统实现了将独占设备变换为若干台对应的逻辑设备的功能。
假脱机(Spooling)技术是广泛用于各种系统的一种行之有效的输入输出手段,这种技术使用比较简单的方法,缓和了处理机与低速输入输出设备速度不匹配的矛盾,提高设备的利用率。
为了更好地掌握这种技术,本实习要求学生独立地用高级语言编写一个Spooling程序来模拟假脱机输入/输出过程。
本实验编制一个Spooling输出进程与另外二个要求输出的进程并发运行。
要求输出进程每运行一次只输出一项信息到输出井,待输出到一个结束标志时,表示一批信息输出完成,在输出井中形成一输出信息块,再由Spooling进程把整个信息块实际输出到打印机或CRT。
因此,进程的运行必须考虑同步问题。
采用进程的随机调度法模拟Spooling输出是合适的,因为各进程的输出应是随机的。
进程基本状态有3种,分别为可执行,等待和结束。
可执行态就是进程正在运行或等待调度的状态;
等待状态又分为等待状态1,等待状态2,等待状态3。
状态变化的条件为:
1〉进程执行完成时,置为“结束”态。
2〉服务程序在将输出信息送输出井时,如发现输出井已满,将调用进程置为“等待状态1”。
3〉SPOOLING进程在进行输出时,若输出井空,则进入“等待状态2”。
4>
SPOOLING进程输出一个信息快后,应立即释放该信息快所占的输出井空间,并将正在等待输出的进程置为“可执行状态"
。
5〉服务程序在输出信息到输出井并形成输出请求信息快后,若SPOOLING进程处于等待态则将其置为“可执行状态”。
6〉当用户进程声请请求输出快时,若没有可用请求快时,调用进程进入“等待状态3"
但是,对于尽管在协作过程中非常认真和努力,但由于水平有限,错误和不足之处在所难免,敬请老师加以批评指正。
各模块的伪码算法
(1)进程控制块(PCB)
structpcb
{
intstatus;
/*进程状态*/
}PCB[3];
PCB(ProcessControlBlock),进程控制块是操作系统用于记录和刻画进程状态及有关信息的数据结构,也是操作系统掌握进程的唯一资料结构,是操作系统控制和管理进程的主要依据。
它包括了进程执行时的情况,以及进程让出处理器所处的状态、断点等信息.对于输出进程和spooling进程两种不同的进程,采用相同的结构处理,包括进程标识,进程状态,输出缓冲,输出指针,信息块首地址,输出长度等内容。
需要支持在不同状态之间的转换,输出缓冲晴空等操作。
(2)请求输出块reqblock
struct{
intreuname;
}reqblock[10];
输出请求块的作用是定义标识要求输出进程的变量和相关信息并且定义输出首地址.要求输出的进程标识,输出长度,输出首地址等内容。
(3)输出井BUFFER
SPOOLING系统为每个请求输出的进程在输出井中分别开辟一个区。
本实验可设计一个二维数组(intbuffer[2][10])作为输出井。
每个进程在输出井最多可占用10个位置。
函数的调用关系图
程序框图如下:
结束返回
X≤0.45,且进程1为执行状态
开始
对各进程的PCB、输出请求块、输出井初始化
生成(0~1)随机数X
判断的X值及进程的状态
执行请求输出用户进程
执行SPOOLing进程
0.45<
X≤0.9,且进程2为执行状态
X>
0.9,且SOOPLing进程为执行状态
进程都结束了吗?
Y
N
图1SPOOLing输出模拟系统主控流程图
测试结果
随机调度算法模拟SPOOLING进程调度程序执行如下:
设计总结
在这两周的操作系统课程设计中,我的题目是:
SPOOLING技术模拟实现,这两周课程设计中,通过该题目的设计过程,学会如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。
在以后的学习中我会更加注意各个方面的能力的协调发展。
在课程设计时遇到了很多的问题,在老师的帮助和对各种资料的查阅中将问题解决,培养了我自主动手,独立研究的能力,为今后在学习工作中能更好的发展打下了坚实的基础。
两周的课程设计很短暂,但其间的内容是很充实的,在其中我学习到了很多平时书本中无法学到的东西,积累了经验,锻炼了自己分析问题,解决问题的能力,并学会了如何将所学的各课知识融会,组织,来配合学习,两周中我收益很大,学到很多。
参考文献
主要参考文献:
1.汤子瀛,哲凤屏.《计算机操作系统》.西安电子科技大学学出版社.
2.王清,李光明.《计算机操作系统》。
冶金工业出版社。
3。
孙钟秀等.操作系统教程.高等教育出版社
4.曾明。
Linux操作系统应用教程.陕西科学技术出版社。
5.张丽芬,刘利雄.《操作系统实验教程》。
清华大学出版社.
6。
孟静,
操作系统教程--原理和实例分析.高等教育出版社
7.周长林,计算机操作系统教程.高等教育出版社
8。
张尧学,计算机操作系统教程,清华大学出版社
9。
任满杰,操作系统原理实用教程,电子工业出版社
致谢
在这两周的操作系统课程设计中,我的题目是:
SPOOLING技术模拟实现,这两周课程设计中,通过该题目的设计过程,进一步理解和熟练掌握课本中所学的各种知识,学会如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。
一个人要完成所有的工作是非常困难和耗时的。
在课程设计时遇到了很多的问题,在老师的帮助和对各种资料的查阅中将问题解决,培养了我自主动手,独立研究的能力,为今后在学习工作中能更好的发展打下了坚实的基础。
两周的课程设计很短暂,但其间的内容是很充实的,在其中我学习到了很多平时书本中无法学到的东西,积累了经验,锻炼了自己分析问题,解决问题的能力,并学会了如何将所学的各课知识融会,组织,来配合学习,两周中我收益很大,学到很多。
基础课学习中为我打下良好的基础,这是我这次课程设计能够顺利完成的前提。
首先感谢我的指导老师王老师,他在我的课程设计过程中提出了指导性的方案和架构,并指引我阅读相关的资料和书籍,使我在不熟悉的领域中仍能迅速掌握新的技术。
我的同学在设计完成后对程序的测试,没有他们,也许就难以发现一些潜在的错误,在此一并表示感谢。
源程序(带注释)
#include〈stdlib。
h>
#include〈time.h>
#include<
stdio。
structpcb{//定义结构体
intstatus;
//进程状态
intlength;
//输出长度
}*PCB[3];
structreq{//请求进程名
intreqname;
//定义名称
intlength;
intaddr;
//本次输出的首地址
}reqblock[10];
intbuffer[2][100];
inthead=0,tail=0;
intt1=5,t2=5;
voidrequest(inti)//定义请求函数
intj,m,s,length=0;
structreq*run;
if(1==i)
t1——;
else
t2——;
printf("
用户%d请求数据:
\n"
i);
//输出标注
run=&reqblock[tail%10];
//定义输出块
run-〉reqname=i;
run—〉length=0;
if(0==tail)
run—>
addr=0;
{
intindex=(tail—1)%10;
run-〉addr=reqblock[index].addr+reqblock[index]。
length;
}
for(m=0;
m〈100;
m++)
{
if(0==buffer[i—1][m])
{
run—>
addr=m;
break;
}
s=0;
while
(1)
j=rand()%10;
if(0==j)
{
length=length;
}
buffer[i-1][(run-〉addr+length)]=s;
printf(”%3d"
,s);
s++;
length++;
}
);
PCB[i-1]->
length+=length;
length=0;
if(2==PCB[2]->
status)
PCB[2]—>
status=0;
tail++;
}
voidspooling()
{
inti,j;
structreq*run;
调用SPOOLING输出服务程序输出数据:
\n”);
run=&reqblock[head%10];
printf(”%d:
run->
reqname);
for(i=0;
i<
run—>
i++)
printf("
%3d"
,buffer[run->
reqname-1][run->
addr+i]);
printf(”\n”);
head++;
for(j=0;
j〈2;
j++)
if(1==PCB[j]—>
PCB[j]-〉status=0;
//程序主函数
voidmain()
{intl,m,n,j,k;
for(l=0;
l<
2;
l++)
for(j=0;
j〈100;
buffer[l][j]=0;
for(n=0;
n〈3;
n++)
structpcb*tmpPcb=(structpcb*)malloc(sizeof(structpcb));
tmpPcb-〉status=0;
tmpPcb->
length=0;
PCB[n]=tmpPcb;
printf(”两个用户进程的请求分别为5,5.\n”);
srand((unsigned)time(NULL));
k=rand()%100;
//用随机数模拟进程执行概率
if(k<
=45)//执行请求输出用户进程1
if((0==PCB[0]—>
status)&&(t1>
0))
request
(1);
elseif((k〈=90)&&
(t2>
0))//执行请求输出用户进程2
if(0==PCB[1]-〉status)
request
(2);
else
spooling();
//执行SPOOLING进程
if((0==t1)&
&
(0==t2)&&(head==tail))
break;
for(m=0;
m<
3;
free(PCB[m]);
PCB[m]=NULL;
//PCB值为空
getchar();
}//主函数结束