SPOOLing系统的设计与实现(上)

章 概述

1.1 SPOOLing系统的背景和意义

随着计算机操作和数据处理的不断增加,I/O设备的速度逐渐成为瓶颈,为了缓和CPU的高速性与I/O设备低速性间的矛盾而引入了脱机输入/输出技术,该技术是在外围机的控制下对程序和数据的输入和输出,也就是在脱离主机的情况下进行的,所以称之为脱机输入/输出方式。而SPOOLing技术则是用软件的方式来模拟脱机技术。在计算机内存中创建一个虚拟输出队列,将输入的作业缓冲在该队列中,再逐次输出到打印机或其他外设上,从而提高计算机系统的效率。SPOOLing系统主要由输入井和输出井、输入缓冲区和输出缓冲区、输入进程和输出进程、井管理程序四部分组成。

SPOOLing系统通过将数据缓存到虚拟输出队列中,可以使计算机在等待缓存输出的同时,继续完成其他任务,减少了I/O操作造成的等待时间,提高了计算机使用效率,实现了虚拟设备的功能,使独占设备变成了共享设备。是计算机系统中一项非常重要的技术。

1.2 SPOOLing系统的主要任务和功能

SPOOLing系统的主要任务是在程序内设计一个输出井。当生成打印任务后,若输出井中无等待执行的打印任务且打印机状态为空闲,则立即送入打印机开始打印;若打印机正在执行上个打印任务,则新任务暂存于输出井。若输出井中有等待执行任务,将新任务添加到已有任务之后,输出井中的任务按先进先出顺序在打印机空闲时依次送入打印机执行。并且能够同时处理不同的输出请求。

具体功能包括:

1.模拟打印机的输出:将外存输出井中的信息发送到打印机等输出设备上进行输出。

2.建立输入井和输出井:使用队列数据结构实现输入井和输出井,存储输入任务和输出请求的数据。

3.存在三个打印任务:打印任务分为执行状态、等待状态和结束状态;按照随机数的大小来判断执行哪一个用户进程。

4.并发处理输入/输出请求:使用多线程和互斥锁机制,实现多个任务的并发处理和同步。

5.对任务进行管理和调度:使用PCB结构体实现任务的管理,进程的状态变化。包括文件序号、占用输出井位置、剩余空间和文件状态等。

6.数据持久化存储:使用文件来存储输出井中的任务,保证任务的持久化存储和恢复。

7.实现人机界面的设计:使用了Java Swing来设计图形界面。界面简洁明了,通俗易懂。能够很清楚的观察到每个用户进程的状态变化、最终的打印输出结果和进程调度的过程显示。

1.3采用的数据结构和算法

该系统主要采用了队列的数据结构来实现输出缓冲区、可用块池等,利用数组和链表的数据结构来实现输出井、输出请求块等。队列具有先进先出的特性,适合用于任务的存储和调度。利用数组便于存储输入井和输出井的信息。利用链表的指针便于存储位置信息。使用互斥锁和条件变量if,通过if判断用户进程或SPOOLing进程满足何种状态后,修改相应进程的状态(唤醒或阻塞)来避免死锁,实现了线程之间的同步和通信,确保任务的安全访问和处理。

该系统主要采用了随机算法来实现进程调度。这与进程输出信息的随机性相一致。三个请求输出的用户进程的调度概率各为30%,SPOOLING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。

1.4创新点和特色

1.并发处理:系统能够同时处理来自多个输入设备的任务,本系统设置了三个用户进程,分别设置为用户进程1,用户进程2,用户进程3,并将任务发送到合适的输出设备上进行输出,提高了系统的效率。降低了系统的死锁和故障风险,提高了系统的可靠性。支持提供为多个用户服务,提高了系统的利用率。支持实时处理的需求,可同时处理多个任务,提高了系统的响应性、性能。

2.多线程和互斥锁机制:采用多线程和互斥锁,实现了对共享资源的同步访问和操作,提高了系统的并发性和数据安全性。增加了程序的响应速度和灵活性。保证了用户之间的数据安全。

3.数据持久化存储:使用文件来存储输出任务,保证了任务的持久化存储和恢复,防止数据丢失。确保了数据的完整性以及应用程序的稳定性。增加了系统的可用性。提高了数据的共享性。

4.简洁明了的代码结构:代码采用了模块化的设计,使得不同功能的模块独立,易于理解和维护。

5.随机算法模拟进程调度:通过随机算法产生随机数,根据随机数大小来选择调度哪一个用户进程。提高了系统的可靠性和精度。

6.使用了图形用户界面:使用java Swing设计了人机界面,界面简洁明了,通俗易懂。能够很清楚的观察到每个用户进程的状态变化、最终的打印输出结果和进程调度的过程显示。能够更方便的对数据进行可视化处理。

章 系统分析和概要设计

2.1需求分析

1.系统分析

设计一个SPOOLing输出进程和两个请求输出的用户进程,以及一个SP00Ling输出服务程序。当请求输出的用户进程希望输出一系列信息时,调用输出服务程序,由输出服务程序将该信息送入输出井。待遇到一个输出结束标志时,表示进程该次的输出文件输出结束。之后,申请一个输出请求块(用来记录请求输出的用户进程的名字、信息在输出井中的位置、要输出信息的长度等),等待SPOOLing进程进行输出。

SPOOLING输出进程工作时,根据请求块记录的各进程要输出的信息,将其实际输出到打印机或显示器。这里,SPOOLing输出进程与请求输出的用户进程可并发运行。

2.概要设计

进程调度采用随机算法,与进程输出信息的随机性相一致。三个请求输出的用户进程的调度概率各为30%,SPOOLING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。

进程基本状态有3种,分别为可执行、等待和结束。可执行态就是进程正在运行或等待调度的状态;等待状态又分为等待状态1、等待状态2和等待状态3。

状态变化的条件为:

①进程执行完成时,置为“结束”态。

②服务程序在将输出信息送输出井时,如发现输出井已满,将调用进程置为“等待状态1”。

③SP00LING进程在进行输出时,若输出井空,则进入“等待状态2”。

④SP00LING进程输出一个信息块后,应立即释放该信息块所占的输出井空间,并将正在等待输出的进程置为“可执行状态”。

⑤服务程序在输出信息到输出井并形成输出请求信息块后,若SP00LING进程处于等待态,则将其置为“可执行状态”。

⑥当用户进程申请请求输出块时,若没有可用请求块时,调用进程进入“等待状态3”。

2.2功能设计

2.2.1功能模块

①进程控制块PCB

structPCB {
int pcb_id; // 进程标识数
int pcb_status; // 进程状态
int pcb_count; // 要输出的文件数
int pcb_out_x; // 进程输出时的临时变量
}

Status有三种状态:其中,0为可执行态;

1为等待状态1,表示输出井满,请求输出的用户进程等待;

2为等待状态2,表示请求输出井空,SP00LING输出进程等待;

3为等待状态3,表示请求输出井满,请求输出的用户进程等待;

4为结束状态,表示进程执行完成。

②请求输出块reqBlock

struct{
int reqname;         /*请求进程名*/
int length;          /*本次输出信息长度*/
int addr;            /*信息在输出井的首地址*/
} reqblock:[10];/*定义一个有10个元素的数组*/

③输出井BUFFER

SP00LING系统为每个请求输出的进程在输出井中分别开辟一个区。本实验可设计一个二维数组(int buffer[3][100])作为输出井。每个进程在输出井最多可占用100个位置。

进程调度函数模块run

采用随机算法,这与进程输出信息的随机性相一致。三个请求输出的用户进程的调度概率各为30%,SPOOLING输出进程为10%,这由随机数发生器产生的随机数来模拟决定。通过随机数来选择调度哪一个进程。

⑤文件生成函数模块User

控制生成文件的过程,以及将这些文件输出到输出井和请求输出块中。首先将生成的文件的数量存储在PCB(进程控制块)中。然后,在生成每个文件的过程中,将文件写入输出井中,并将文件的位置信息写入请求输出块中。当输出井或请求输出块不足时,该函数将相应的进程状态设置为等待状态,并返回已生成的文件数量。在生成完所有文件后,该函数设置进程状态为完成状态,并返回生成的文件数量。

⑥进程函数模块SPOOling

这个进程负责处理用户进程的输出请求。使用一个while循环遍历输出请求块。如果请求输出块不为空,进程读取块的内容并修改输出缓冲区的第一个文件位置指针。如果有一个进程因为缺少输出块而处于等待状态3,进程将新释放的空闲输出块分配给该进程,更新该进程的状态并唤醒它。如果有一个进程因为等待输出井而处于等待状态1,进程将新释放的空闲输出块分配给该进程并唤醒它。该进程将一直运行,直到没有可用的输出请求或者直到所有用户进程都完成了它们的任务。如果没有可用的输出块,输出进程将进入等待状态2,直到有可用的块为止。

2.2.2流程和层次关系

(1)主程序的流程:

首先对各个进程的PCB、输出请求块、输出井进行初始化,然后利用随机数生成器产生随机数,判断随机数X的值以及进程的状态,如果X<=0.3且进程1为执行状态,则执行请求输出用户进程1;如果0.3<X<=0.6且进程2为执行状态,则执行请求输出用户进程2;如果0.6<X<=0.9且进程3为执行状态,则执行请求输出用户进程3;如果X>0.9且SPOOLing进程为执行状态,则执行SPOOLing进程。如果进程都结束了,则结束。反之,则重新生成随机数x。

(2)各模块间的层次关系:

首先进入user函数里面,根据参数和键盘的输入值设置进程id和进程计数,然后不断循环生成文件,直到达到指定文件个数。在生成文件过程中,随机生成一个数作为文件内容并存储到输出井中。如果输出井已满,则进入等待状态1,并释放输出井的空间。如果没有空闲输出块,则进入等待状态3。如果有空闲输出块,则将文件在输出井的位置信息存储到请求输出块中,并将请求输出块分配给文件。同时调用run函数,在run函数中,通过判断随机数来选择调用哪一个用户进程和Spool函数,在Spool函数中判断请求输出块是否为空,来判断等待状态。当所有用户进程和SPOOLing进程都完成时,打印工作结束。

2.2.3数据组织方式和程序控制结构

在run函数中,主要采用了队列和数组的数据组织方式,来存取用户进程。通过顺序结构、选择结构、循环结构,来判断选择哪一个用户进程调度和判断是否每一个用户进程都已经调度完成。

在user函数中,主要采用了数组、链表的数据组织方式,利用数组来存取用户进程的文件个数、文件内容和输出井。利用链表来存放输出井的文件首地址。通过顺序结构、选择结构、循环结构,来判断输出井是否存满和判断文件数目是否达到设定数量,进而结束循环,返回已输出的文件数。

在spool函数中,主要采用了数组、链表的数据组织方式,利用数组来存放输出井中的文件。利用链表存放请求输出块第一个文件位置。通过顺序结构、选择结构、循环结构,来判断当前打印的文件是由哪一个用户进程生成的和判断请求输出块是否为空以及判断打印任务是否全部完成。

如果对您有帮助的话,能否支持一下博主?
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇