SPOOKING技术
- 一、实验目的
- 二、实验内容
- 三、实验准备
- 1、设计一个实现SPOOLING技术的进程
- 2、设计进程调度算法
- 3、进程状态
- 4、数据结构
- 5、编程说明
- 6、程序框图
- 四、实验要求
- 1、数据结构
- 2、程序流程图
- 代码运行结果
一、实验目的
理解和掌握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,自己的学号是sumsum = 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--;elseT2--;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)//若没有可用请求块时,调用进程进入"等待状态3PCB[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);}elseSpooling();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);}elseSpooling();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--;elseT2--;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)//若没有可用请求块时,调用进程进入"等待状态3PCB[j]->status = 0;}
}