实验6 SPOOLING技术.docx
《实验6 SPOOLING技术.docx》由会员分享,可在线阅读,更多相关《实验6 SPOOLING技术.docx(11页珍藏版)》请在冰豆网上搜索。
实验6SPOOLING技术
实验6SPOOLING技术(2学时)
一、实验目的
理解和掌握SPOOLING技术。
二、实验内容
编写程序实现SPOOLING技术的模拟。
三、实验要求
1、设计一个实现SPOOLING技术的进程
设计一个SPOOLING输出进程和两个请求输出的用户进程及一个SPOOLING输出服务程序。
SPOOLING输出进程工作时,根据请求块记录的各进程要输出的信息,将其实际输出到打印机或显示器。
这里,SPOOLING进程与请求输出的用户进程可并发运行。
2、设计进程调度算法
进程调度采用随机算法,这与进程输出信息的随机性相一致。
两个请求输出的用户进程的调度概率各为45%,SPOOLING输出进程为10%,这由随机数发生器产生的随机数模拟决定。
3、进程状态
进程基本状态有3种,分别为可执行、等待和结束。
可执行状态就是进程正在运行或等待调度的状态;等待状态又分为等待状态1、等待状态2、等待状态3。
状态变化的条件为:
(1)进程执行完成时,置为“结束”状态。
(2)服务程序在将输出信息送至输出井时,如发现输出井已满,将调用进程置为“等待状态1”。
(3)SPOOLING进程在进行输出时,若输出井空,则进入“等待状态2”。
(4)SPOOLING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。
(5)服务程序在输出信息到输出井并形成输出请求信息块后,若SPOOLING进程处于等待状态则将其置为“可执行状态”。
(6)当用户进程申请请求输出块时,若没有可用请求块时,调用进程进入“等待状态3”。
4、数据结构
1)进程控制块PCB
structpcb
{
intstatus;
intlength;
}pcb[3];
其中status表示进程状态,其取值:
0表示可执行状态;
1表示等待状态1;
2表示等待状态2;
3表示等待状态3
2)请求输出块reqblock
struct{
intreqname;//请求进程名
intlength;//本次输出信息长度
intaddr;//信息在输出井的首地址
}reqblock[10];
3)输出井BUFFER
SPOOLING系统为每个请求输出的进程在输出井中分别开辟一个区。
本实验可设计一个二维数组(intbuffer[2][10])作为输出井。
每个进程在输出井最多可占用10个位置。
5、编程说明
为两个请求输出的用户进程设计两个输出井。
每个可存放10个信息,即buffer[2][10]。
当用户进程将其所有文件输出完时,终止运行。
为简单起见,用户进程简单的设计成:
每运行一次,随机输出数字0~9之间的一个数,当输入10个数时形成一个请求信息块,填入请求输出信息块reqblock结构中。
#include
#include
#include
#include
//用户进程的数量
#definePRO_CNT2
//输出井的长度
#defineBUF_LEN10
//可执行状态
#defineSTAT_EXE0
//等待状态1,等待可用输出井
#defineSTAT_WAT_BUF1
//等待状态2,等待输出内容
#defineSTAT_WAT_OUT2
//等待状态3,等待输出信息块
#defineSTAT_WAT_REQ3
//结束状态
#defineSTAT_END4
structpcb{
intstatus;
intlength;
};
structreq{
intreqname;//请求进程名
intlength;//本次输出信息长度
intaddr;//信息在输出井的首地址
};
//进程控制块
pcbpcbs[PRO_CNT];
intspoolingState;
//请求输出块
reqreqblocks[10];
intreqCnt=0;
//输出井
intbuffer[PRO_CNT][BUF_LEN];
intbufferCnt[PRO_CNT]={0,0};
//SPOOLING服务程序程序
voidspoolingServer(intreqname,intc){
printf("进程p%d输出%d。
\n",reqname+1,c);
buffer[reqname][bufferCnt[reqname]++]=c;
if(bufferCnt[reqname]==10||pcbs[reqname].length==0){
pcbs[reqname].status=STAT_WAT_BUF;
req&r=reqblocks[reqCnt++];
r.reqname=reqname;
r.addr=0;
r.length=bufferCnt[reqname];
if(spoolingState==STAT_WAT_OUT){
spoolingState=STAT_EXE;
}
}
}
//执行用户进程
voiduserProcess(intidx){
pcb&p=pcbs[idx];
if(p.status!
=STAT_EXE)return;
if(p.length==0){
printf("进程p%d输出结束。
\n",idx+1);
p.status=STAT_END;
return;
}
p.length--;
spoolingServer(idx,rand()%10);
}
voidspooling(){
if(spoolingState==STAT_EXE){
if(reqCnt==0){
spoolingState=STAT_WAT_OUT;
}else{
intidx=reqblocks[0].reqname;
printf("进程p%d输出%d个字符:
",idx+1,reqblocks[0].length);
for(inti=0;iputs("");
pcbs[idx].status=STAT_EXE;
bufferCnt[idx]=0;
for(inti=0;ireqCnt--;
if(reqCnt==0)spoolingState=STAT_WAT_OUT;
}
}
}
intmain(){
srand(time(NULL));
spoolingState=STAT_EXE;
for(inti=0;i<2;i++){
pcbs[i].length=rand()%20;
printf("用户进程p%d,需要输出%d个字符。
\n",i+1,pcbs[i].length);
pcbs[i].status=STAT_EXE;
}
while(pcbs[0].status!
=STAT_END||pcbs[1].status!
=STAT_END){
intr=rand()%100;
if(r<45)userProcess(0);
elseif(r<90)userProcess
(1);
elsespooling();
}
system("pause");
return0;
}
#include
#include
#include
#include
//用户进程的数量
#definePRO_CNT2
//输出井的长度
#defineBUF_LEN10
//可执行状态
#defineSTAT_EXE0
//等待状态1,等待可用输出井
#defineSTAT_WAT_BUF1
//等待状态2,等待输出内容
#defineSTAT_WAT_OUT2
//等待状态3,等待输出信息块
#defineSTAT_WAT_REQ3
//结束状态
#defineSTAT_END4
structpcb{
intstatus;
intlength;
};
structreq{
intreqname;//请求进程名
intlength;//本次输出信息长度
intaddr;//信息在输出井的首地址
};
//进程控制块
pcbpcbs[PRO_CNT];
intspoolingState;
//请求输出块
reqreqblocks[10];
intreqCnt=0;
//输出井
intbuffer[PRO_CNT][BUF_LEN];
intbufferCnt[PRO_CNT]={0,0};
//SPOOLING服务程序程序
voidspoolingServer(intreqname,intc){
printf("进程p%d输出%d。
\n",reqname+1,c);
buffer[reqname][bufferCnt[reqname]++]=c;
if(bufferCnt[reqname]==10||pcbs[reqname].length==0){
pcbs[reqname].status=STAT_WAT_BUF;
req&r=reqblocks[reqCnt++];
r.reqname=reqname;
r.addr=0;
r.length=bufferCnt[reqname];
if(spoolingState==STAT_WAT_OUT){
spoolingState=STAT_EXE;
}
}
}
//执行用户进程
voiduserProcess(intidx){
pcb&p=pcbs[idx];
if(p.status!
=STAT_EXE)return;
if(p.length==0){
printf("进程p%d输出结束。
\n",idx+1);
p.status=STAT_END;
return;
}
p.length--;
spoolingServer(idx,rand()%10);
}
voidspooling(){
if(spoolingState==STAT_EXE){
if(reqCnt==0){
spoolingState=STAT_WAT_OUT;
}else{
intidx=reqblocks[0].reqname;
printf("进程p%d输出%d个字符:
",idx+1,reqblocks[0].length);
for(inti=0;iputs("");
pcbs[idx].status=STAT_EXE;
bufferCnt[idx]=0;
for(inti=0;ireqCnt--;
if(reqCnt==0)spoolingState=STAT_WAT_OUT;
}
}
}
intmain(){
srand(time(NULL));
spoolingState=STAT_EXE;
for(inti=0;i<2;i++){
pcbs[i].length=rand()%20;
printf("用户进程p%d,需要输出%d个字符。
\n",i+1,pcbs[i].length);
pcbs[i].status=STAT_EXE;
}
while(pcbs[0].status!
=STAT_END||pcbs[1].status!
=STAT_END){
intr=rand()%100;
if(r<45)userProcess(0);
elseif(r<90)userProcess
(1);
elsespooling();
}
system("pause");
return0;
}