(1) 课程设计题目及内容
设计模拟一个SPOOLING假脱机输出程序
设计一个SPOOLING输出进程和两个请求输出的用户进程,以及一个SPOOLING输出服务程序request。当用户进程希望输出一系列信息时,调用SPOOLING输出服务程序request,由输出服务程序将该信息送入输出井。待给出一个结束标志时,表示进程该次的文件输出结束。之后,申请一个输出请求块,用来记录请求输出的用户进程的名字、要输出的文件名以及要输出信息的长度等。等待SPOOLING输出进程进行输出。这里,SPOOLING输出进程与请求输出的用户进程可并发运行。SPOOLING输出进程工作时,根据请求块记录的各进程要输出的信息,将其实际输出到打印机或显示器,这里记录到一个文件中。
(2) 程序中使用的数据结构及主要符号说明
进程标识用结构体pcb表示,整型id表示进程标识数,status表示进程状态。
struct pcb
{
int id; // 进程标识数
int status; // 进程状态
};
文件标识用结构体filehandle表示,整型file_length表文件长度,在开始进程前随机写入,file_already表已写入输出井中的长度。
struct filehandle //文件标识
{
int file_length;//文件长度
int file_already;//文件已写入缓冲的长度
};
申明一个全局二维指针,用于申请动态二维数组时表示两个进程的文件
extern filehandle FH;
status = 0 为可执行态;
status = 1 为等待状态1,表示请求输出块用完,请求输出的用户进程等待;
status = 2 为等待状态2, 表示输出井空,SPOOLING输出进程等待;
status = 3 为结束态,进程执行完成。
请求块用结构体block表示,整型reqname记录请求块对应的进程名,sta对应该请求块在输出井中开始输出的起点,length表示该请求块对应的写入数据总长度。
struct block
{
int reqname; // 请求进程名
int sta; //请求块对应输出井中起点
int length; // 本次输出信息长度
};
extern pcb PCB[3];
extern block reqblock[block_num];
extern int T[2];//进程1、2需要完成输出的文件数目
extern int t[2];//进程1、2已经完成输出的文件数目
extern int n_in, n_out;//送取数据时的块数标记,取值为0~9(超过9时模10),因为有C3作标记,无需考虑循环队列的判空判满,只要考虑各自位置即可
整型C3标记请求块剩余数目,同时循环队列判空判满
extern int C3;//请求块剩余块数
为每个进程开辟一个文件共享区
extern int buffer[2][buffer_size];//输出井
extern int bufferleft[2];//输出井剩余空间
(3) 程序流程图和带有注释的源程序
程序流程图
Spooling.h
#include <iostream>
#include <time.h>
#define p1_fnum 5 //进程一需要输出的文件数目
#define p2_fnum 2 //进程二需要输出的文件数目
#define f_maxsize 10 //一个文件所占输出井最大空间
#define buffer_size 30 //一块输出井大小
#define block_num 10 //请求块数目
struct pcb
{
int id; // 进程标识数
int status; // 进程状态
};
struct filehandle //文件标识
{
int file_length;//文件长度
int file_already;//文件已写入缓冲的长度
};
extern filehandle** FH;
/*
status = 0 为可执行态;
status = 1 为等待状态1,表示请求输出块用完,请求输出的用户进程等待;
status = 2 为等待状态2, 表示输出井空,SPOOLING输出进程等待;
status = 3 为结束态,进程执行完成。
*/
struct block
{
int reqname; // 请求进程名
int sta; //请求块对应输出井中起点
int length; // 本次输出信息长度
};
extern pcb PCB[3];
extern block reqblock[block_num];
extern int T[2];//进程1、2需要完成输出的文件数目
extern int t[2];//进程1、2已经完成输出的文件数目
extern int n_in, n_out;//送取数据时的块数标记,取值为0~9(超过9时模10),因为有C3作标记,无需考虑循环队列判空判满,只要考虑各自位置即可
extern int C3;//请求块剩余块数
extern int buffer[2][buffer_size];//输出井
extern int bufferleft[2];//输出井剩余空间
void systemInitialize();//进程、输出井初始化
int getpid(); //获取随机调度的进程
void printblock(int num);//在spooling中打印对应块的内容
int getfinish();//查询完成资源数
void renewprocess();//更新子进程状态
void spooling();//spooling调度算法
void request(int pid);//输出进程请求
Spooling.cpp
#