SPOOKING技术
一、实验目的
理解和掌握SPOOLING假脱机技术
二、实验内容
通过SPOOLING技术可将一台物理I/O设备虚拟为多台逻辑I/O设备,同样允许多个用户共享一台物理I/O设备,从而使其成为虚拟设备。该技术广泛应用与各种计算机的I/O,通过采用预输入和缓输出的方法,使用共享设备的一部分空间来模拟独占设备,以提高独占设备的利用率。
三、实验准备
1、设计一个实现SPOOLING技术的进程
设计一个SPOOLING输出进程和两个请求输出的用户进程及一个SPOOLING输出服务程序。
SPOOLING输出进程工作时,根据请求块记录的各进程要输出的信息,将其实际输出到打印机或显示器。这里,SPOOLING进程与请求输出的用户进程可并发运行。
2、设计进程调度算法
进程调度采用随机算法,这与进程输出信息的随机性相一致。两个请求输出的用户进程的调度概率各为45%,SPOOLING输出进程为10%,这由随机数发生器产生的随机数模拟决定。
3、进程状态
进程基本状态有3种,分别为可执行、等待和结束。可执行状态就是进程正在运行或等待调度的状态;
等待状态又分为等待状态1、等待状态2、等待状态3。
状态变化的条件为:
①进程执行完成时,置为“结東”状态。
②服务程序在将输出信息送至输出井时,如发现输出井已满,将调用进程置为“等待状态1”。
③SPOOLING进程在进行输出时,若输出井空,则进入“等待状态2”。
④当用户进程申请请求输出块时,若没有可用请求块时,调用进程进入“等待状态3”。
⑤SPOOLING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。
⑥服务程序在输出信息到输出井并形成输出请求信息块后,若SPOOLING进程处于等待状态则将其置为“可执行状态”
4、数据结构
1)进程控制块PCB
structpcb{
intstatus:
intlength
}PCBL3];
其中status表示进程状态,其取值:
0表示可执行状态
1表示等待状态1;
2表示等待状态2;
3表示等待状态3。
2)请求输出块reqblock
struct{
intreqname;//请求进程名
intlength;//本次输出信息长度
intaddr;//信息在输出井的首地址
}reblock[10];
3)输出井BUFFER
SPOOLING系统为每个请求输出的进程在输出井中分别开辟一个区。本实验可设计一个二维数组(intbuffer[2][10])作为输出井。每个进程在输出井最多可占用10个位置。
5、编程说明
为两个请求输出的用户进程设计两个输出井。每个可存放10个信息,即buffer[2][10]。当用户进程将其所有文件输出完时,终止运行。
为简单起见,用户进程简单地设计成:每运行一次,随机输出数字0~9之间的一个数,当输入10个数时形成一个请求信息块,填入请求输出信息块reqlock结构中。
6、程序框图
SPOOLING输出模拟系统主控流程图如图所示。
四、实验要求
1、分析程序所定义使用的数据结构;
2、分析程序的结构,并画出程序流程图;
3、撰写实验报告;
1、数据结构
struct process
{
int status;//进程状态
int length;//数据长度
}*PCB[3];
struct requset
{
int reqName;//用户名字
int length;//输出数据长度
int addr;//地址寄存器
}reqBlock[10];
int Buffer[2][100];//定义#
int Head = 0;//打印用户请求的的数据<10的随机数
int Tail = 0;//请求用户数据<10的随机数
int T1 = 0;//用户1请求次数定义
int T2 = 0;//用户2请求次数定义
void Request(int i);//i=1表示用户进程1;i=2表示用户进程2
void Spooling();
2、程序流程图
获取本地时间代码
void Time()
{
time_t t;//将t声明为时间变量
struct tm *p;//struct tm是一个结构体,声明一个结构体指针
time(&t);
p=localtime(&t);//获得当地的时间
int s = 7;//定义一个值
int k = 7;
int sum;//计算出k和s,自己的学号是sum
sum = s * k;
printf("\n");
printf(" 学号展示\n",sum);
printf(" 自己的姓名\n");
printf("\n");
printf("操作系统实验展示于%d年%d月%d日 %d时%d分%d秒\n",1900 + p -> tm_year, 1 + p -> tm_mon, p -> tm_mday, p -> tm_hour, p -> tm_min, p -> tm_sec);
//输出当前本地的时间
}
请求函数代码
void Request(int i)
{
int j = 0;
int m = 0;
int length = 0;
struct requset *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;
else
{
int index = (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;
}
}
while(1)
{
j = rand()%10;
if(0 == j)
{
run -> length = length;
break;
}
Buffer[i-1][(run->addr+length)] = j;
printf("%3d",j);
length++;
}
printf("\n");
PCB[i-1]->length += length;
printf("此时process[%d]中length的值为%d\n",i,length);
printf("*******************************\n");
length = 0;
if(2 == PCB[j]->status)
PCB[j]->status = 0;
Tail++;
}
SPOOLING代码
void Spooling()
{
int i = 0;
int j = 0;
struct requset *run;
printf("调用SPOOLING输出服务程序输出数据:\n");
run =& reqBlock[Head%10];
printf("用户%d请求的数据:\n",run->reqName);
for(i = 0; i < run->length; i++)
{
printf("%3d",Buffer[run->reqName-1][run->addr+i]);
}
printf("\n");
printf("\n***********************************\n");
Head++;
for(j = 0; j < 2; j++)
{
if(1 == PCB[j]->status)//若没有可用请求块时,调用进程进入"等待状态3
PCB[j]->status = 0;
}
}
主函数代码
int main()
{
int l = 0;
int j = 0;
int n = 0;
int m = 0;
int k = 0;
for(l = 0; l < 2; l++)
for(j = 0; j < 100; j++)
Buffer[l][j] = 0;
for(n = 0; n < 3; n++)
{
struct process *tmpprocess = (struct process*)malloc(sizeof(struct process));
tmpprocess->status = 0;
tmpprocess->length = 0;
PCB[n] = tmpprocess;
}
Time();
printf("用户1请求次数为:\n");
scanf("%d",&T1);
printf("用户2请求次数为:\n");
scanf("%d",&T2);
srand((unsigned)time(NULL));
while(1)
{
k = rand()%100;
printf("\n");
printf("当前K值为%d\n",k);
if((k <= 45) && (T1 > 0))
{
if((0 == PCB[0]->status) && (T1 > 0))
Request(1);
}
else
if((k <= 90) && (T2 > 0))
{
if(0 == PCB[1]->status)
Request(2);
}
else
Spooling();
if((0 == T1) && (0 == T2) && (Head == Tail))
break;
}
for(m = 0; m < 3; m++)
{
free(PCB[m]);
PCB[m] = NULL;
}
getchar();
}
全部代码展示
#include<stdio.h>
#include<iostream>
#include<time.h>
#include<stdlib.h>
struct process
{
int status;//进程状态
int length;//数据长度
}*PCB[3];
struct requset
{
int reqName;//用户名字
int length;//输出数据长度
int addr;//地址寄存器
}reqBlock[10];
int Buffer[2][100];//定义#
int Head = 0;//打印用户请求的的数据<10的随机数
int Tail = 0;//请求用户数据<10的随机数
int T1 = 0;//用户1请求次数定义
int T2 = 0;//用户2请求次数定义
void Request(int i);//i=1表示用户进程1;i=2表示用户进程2
void Spooling();
void Time()
{
time_t ti;//将t声明为时间变量
struct tm *p;//struct tm是一个结构体,声明一个结构体指针
time(&ti);
p = localtime(&ti);//获得当地的时间
int s = 7;
int k = 7;
int sum;
sum = s * k;
printf("***********************************\n");
printf("****** SPOOLING技术模拟系统 ****\n");
printf("****** 学号 *********\n",sum);
printf("****** 姓名 *********\n");
printf("***********************************\n");
printf("操作系统实验展示于%d年%d月%d日 %d时%d分%d秒\n",1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p ->tm_sec);
printf("---------------------------------------------\n");
}
int main()
{
int l = 0;
int j = 0;
int n = 0;
int m = 0;
int k = 0;
for(l = 0; l < 2; l++)
for(j = 0; j < 100; j++)
Buffer[l][j] = 0;
for(n = 0; n < 3; n++)
{
struct process *tmpprocess = (struct process*)malloc(sizeof(struct process));
tmpprocess->status = 0;
tmpprocess->length = 0;
PCB[n] = tmpprocess;
}
Time();
printf("用户1请求次数为:\n");
scanf("%d",&T1);
printf("用户2请求次数为:\n");
scanf("%d",&T2);
srand((unsigned)time(NULL));
while(1)
{
k = rand()%100;
printf("\n");
printf("当前K值为%d\n",k);
if((k <= 45) && (T1 > 0))
{
if((0 == PCB[0]->status) && (T1 > 0))
Request(1);
}
else
if((k <= 90) && (T2 > 0))
{
if(0 == PCB[1]->status)
Request(2);
}
else
Spooling();
if((0 == T1) && (0 == T2) && (Head == Tail))
break;
}
for(m = 0; m < 3; m++)
{
free(PCB[m]);
PCB[m] = NULL;
}
getchar();
}
void Request(int i)
{
int j = 0;
int m = 0;
int length = 0;
struct requset *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;
else
{
int index = (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;
}
}
while(1)
{
j = rand()%10;
if(0 == j)
{
run -> length = length;
break;
}
Buffer[i-1][(run->addr+length)] = j;
printf("%3d",j);
length++;
}
printf("\n");
PCB[i-1]->length += length;
printf("此时process[%d]中length的值为%d\n",i,length);
printf("*******************************\n");
length = 0;
if(2 == PCB[j]->status)
PCB[j]->status = 0;
Tail++;
}
void Spooling()
{
int i = 0;
int j = 0;
struct requset *run;
printf("调用SPOOLING输出服务程序输出数据:\n");
run =& reqBlock[Head%10];
printf("用户%d请求的数据:\n",run->reqName);
for(i = 0; i < run->length; i++)
{
printf("%3d",Buffer[run->reqName-1][run->addr+i]);
}
printf("\n");
printf("\n***********************************\n");
Head++;
for(j = 0; j < 2; j++)
{
if(1 == PCB[j]->status)//若没有可用请求块时,调用进程进入"等待状态3
PCB[j]->status = 0;
}
}