设计模拟一个SPOOLING假脱机输出程序

您所在的位置:网站首页 spooling技术的应用 设计模拟一个SPOOLING假脱机输出程序

设计模拟一个SPOOLING假脱机输出程序

#设计模拟一个SPOOLING假脱机输出程序| 来源: 网络整理| 查看: 265

(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 #include #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 #include"SPOOLING.h" pcb PCB[3]; block reqblock[10]; filehandle** FH = (filehandle**)(malloc(sizeof(filehandle*) * 2)); int T[2] = { p1_fnum, p2_fnum };//进程1、2需要完成输出的文件数目 int t[2] = { 0,0 };//进程1、2已经完成输出的文件数目 int n_in = 0, n_out = 0;//送取数据时的块数标记,取值为0~9(超过9时模10),因为有C3作标记,无需考虑循环队列判空判满,只要考虑各自位置即可 int C3 = block_num;//请求块剩余块数 int buffer[2][buffer_size];//输出井 int bufferleft[2] = { buffer_size,buffer_size };//输出井剩余空间 void systemInitialize() { FH[0] = (filehandle*)malloc(sizeof(filehandle) * p1_fnum); FH[1] = (filehandle*)malloc(sizeof(filehandle) * p2_fnum); std::cout FH[1][i].file_already = 0; FH[1][i].file_length = rand() % 20 + 1; std::cout int p = rand() % 100 + 1; if (p return 1; } else { return 2; } } int getfinish() { int finish = 0; for (int i = 0; i finish++; } } return finish; } void printblock(int num) { std::cout if (C3 == block_num) { if (getfinish() == 2)//其它进程已结束,SPOOLING进程结束 { std::cout PCB[0].status = 0; for (; n_out != n_in; n_out = (n_out + 1) % 10) { printblock(n_out); C3++;//所剩块加一 } bufferleft[0] = buffer_size; bufferleft[1] = buffer_size; if (PCB[1].status == 1) { std::cout if (C3 == 0)//请求块剩余数为0或对应的输出井区域所剩空间不足 { std::cout //写文件,如果已经是最后一个字符了,写完break,表明文件写完 if (FH[pid - 1][t[pid - 1]].file_already == FH[pid - 1][t[pid - 1]].file_length - 1) { pen = 0; } else { pen = rand() % 9 + 1; } buffer[pid - 1][buffer_size - bufferleft[pid - 1] + l] = pen;//写入输出井 FH[pid - 1][t[pid - 1]].file_already++; //每次写字符,该文件已写字符数往后走一步 l++; std::cout PCB[pid].status = 1; } bufferleft[pid-1] -= l; reqblock[n_in].length = l;//文件输出流长度写入该块 C3--;//所剩请求块减一 n_in = (n_in + 1) % block_num; //写入块往下走 if (PCB[0].status == 2) { std::cout PCB[1].status = 3; } if (T[1] == t[1]) { PCB[2].status = 3; } } (4) 执行程序名,并打印程序运行时的初值和运算结果

在这里插入图片描述 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3