实验四 设备管理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SPOOLING模拟系统
一、实验目的
假脱机(Spooling)技术是广泛用于各种系统的一种行之有效的输入输出手段,这种技术使用比较简单的方法,缓和了处理机与低速输入输出设备速度不匹配的矛盾,提高设备的利用率。为了更好地掌握这种技术,本实习要求学生独立地用高级语言编写一个Spooling程序来模拟假脱机输入输出过程。
二、实验要求及实验环境
可将 Spooling 输入输出程序编制成一个独立的进程与其它要求输入输出的进程并发工作。Spooling 进程负责从卡片机或光电读带机等设备读入信息送到磁盘或磁鼓的输入井中,或是把磁盘、磁鼓输出井的信息块送到打印机或 CRT 等设备输出。其余进程只要求编写输入输出部分的程序,可不考虑其它操作。
本实验编制一个 Spooling 输出进程与另外二个要求输出的进程并发运行。要求输出进程每运行一次只输出一项信息到输出井,待输出到一个结束标志时,表示一批信息输出完成,在输出井中形成一输出信息块,再由 Spooling 进程把整个信息块实际输出到打印机或CRT。因此,进程的运行必须考虑同步问题。
采用进程的随机调度法模拟 Spooling输出是合适的,因为各进程的输出应是随机的。
(1)进程调度采用随机调度法,二个要求输出进程的调度概率各为45%,Spooling 进程为 10%。
(2)可为进程设置三种工作状态:可运行状态,不可运行状态 3和结束状态。为了区分要求输出进程和Spooling 进程处于不可运行状态的不同原因,又把不可运行状态分成不可运行状态 1 和2。分别叙述如下:
①进程执行完毕后应置成“结束状态”。
②要求输出进程在输出信息时,如发现输出井已满,应置成“不可运行状态1”。
③Spooling 进程在输出井空时应置成“不可运行状态2”。
④Spooling 进程输出一个信息块后,应释放该信息块所占的输出井位置,并将正在等待输出的进程置成“可运行状态”。
⑤要求输出进程在输出信息到输出井并形成信息块后,应将Spooling进程置成“可运行状态”。
三、设计思想
1.数据结构:
①进程控制块PCB:
struct {
int d;进程标识数
int status;进程状态
int outpointer;输出指针
int firetaddr;信息块首地址
int length;输出长度
int outbufword;输出缓冲字
}PCB[3]
status=0为可执行态
1为等待状态输出井满
2为等待状态无请求块
3为结束态
outpointer指向输出井的第一个空位置。
②输出请求块 reqblock:
struct {
int reqname;请求进程名
int length;本次输出长度
int addr;本次输出的首地址
}reblock[10]
③输出井 well:SPOOLING 系统为每一个请求输出的进程在输出井中分别开辟一个区域。本例设置一个数组int well[2][100]作为输出井。
2.程序框图。程序框图见附图1、附图2和附图3。
四、
#include
struct info_PCB {
long ID;//进程标识long status;//状态long po;//输出指针
long head;//信息块首地址
long count;//输出长度
long wait[1000];//输出缓冲
}PCB[4];
struct info_block
{
long ID;//要求输出的进程
long len;//输出长度
long head;//输出首地址
}block[128];
struct info_wall
{
long num[10000];//输出内容
long open,closed;//队列指针
}wall[3];
long K[3],L1,L2[3];
long n;
void input()//输入函数
{
printf("Input the times of user1's output file:"); scanf("%ld",&K[1]);
printf("Input the times of user2's output file:"); scanf("%ld",&K[2]);
}
void init()//初始化函数
{
L1=10;
L2[1]=L2[2]=100;
memset(PCB,0,sizeof(PCB));
PCB[1].ID=1;
PCB[2].ID=2;
PCB[3].ID=3;
PCB[3].status=2;
memset(wall,0,sizeof(wall)); 10
n=0;
}
void work()//模拟进程调度
{
long r;
long k;
long a,b;
long i,j;
while (PCB[1].status!=3 || PCB[2].status!=3 || PCB[3].status!=3) {
r=rand()%100+1;//用随机数模拟进程执行概率
if (r<=45)
{
k=1;
}
else
{
if (r<=90)
k=2;
else
k=3;
}
if (PCB[k].status!=0)
continue;
switch (k)
{
case 1:
case 2:
//输出进程k
a=rand()%10;
++PCB[k].po;
PCB[k].wait[PCB[k].po]=a;
if (a==0)
{
b=wall[k].closed+1;
for (i=1;i<=PCB[k].po;i++)
{
wall[k].num[++wall[k].closed]=PCB[k].wait[i];
}
PCB[k].po=0; 11
PCB[k].count++;
if (PCB[k].count==K[k])
//进程执行完毕后应置成"结束状态"。
{
PCB[k].status=3;
}
if (PCB[3].status==2)