进程状态迁移

2022-09-28 14:17:57
  • 目的

  写一个程序描述进程状态迁移过程,理解进程概念、状态转换及其控制。

  • 内容

1)提供导致进程状态变化的调用接口,包括创建、删除、调度、阻塞、时间到、挂起、激活等。
2)实现进程列表显示的接口。
3)这里设计的进程是一个假设的对象实体,是由程序自己创建和删除,不是系统维护的进程。
  • 需求(需要实现哪些功能)

初始化进程基本数据;
向就绪队列添加进程,(考虑优先级);
从就绪队列中取进程;
将被阻塞的执行进程放入阻塞队列;
唤醒阻塞队列中的进程;
完成的进程放入消亡队列;
获取信息(各队列数据的获取)。
  • 主要数据结构介绍

  • 主要模块算法介绍

1.Process.java

该类是进程的实体类,封装了进程的名字,优先级,时间片数等一系列进程的信息和获取进程信息的get方法,修改进程信息的set方法以及一个run()方法,run()方法是执行该进程的方法。

run()方法每执行一次,优先级-1,优先级=0时,不再降级;时间片数-1,时间片数=0时,进程执行完成,终止进程,返回值-1;正常执行返回值1。

2.ProcessBuilder.java

进程构建者类,封装了一个getProcessFactory()方法,提供唯一的单例ProcessFactory进程工厂对象。

3.ProcessFactory.java

进程工厂类,封装一个Random类对象和getProcess(String name ,int status)方法,使用getProcess()方法,传入进程名name和进程状态status以及使用Random对象的nextInt()方法生成的随机数用作进程时间片数和进程优先级数,最终创建一个进程对象并返回给调用者。

4.HPF.java

HPF类中,使用了高优先权优先调度算法来控制进在队列中的存取以及其运行,并将执行过程实时可视化到用户界面当中。

HPF类中有runningProcess变量用于存储正在运行的进程和三个队列变量(分别表示就绪队列,阻塞队列,消亡队列),还有:

  • Init()方法是初始化HPF类中的基本变量。
  • wakeUpProcess()方法:唤醒被阻塞的线程,如果当前正在被执行的线程被阻塞了,立即唤醒当前被阻塞的线程(只在单步执行时才有效,因为自动执行时,被阻塞的线程会立即被加入阻塞队列),否则唤醒阻塞队列中一个线程,将其加入到就绪队列中;
  • robotization()方法:自动化的调度和执行进程,是对next()方法的再封装;
  • next()方法:单步调度和执行一次进程;
  • BloockedNow()方法:消亡当前进程并将其放入消亡队列中,每次进程执行完都会调用该方法进行判断,如果进程的时间片数=0,重置该进程的状态为“消亡”,放入消亡队列中,消亡队列中的进程将不再被调用;
  • queueToTextArea()方法;实时同步三个队列信息到用户界面上,每一次进程执行之后都会被调用一次。

5.ProcessManagement.java

processManagement类是构建进程管理界面的类,其中包含大量界面控件的定义以及控件的功能实现,在这里不一一赘述。

  • 程序实现环境及使用说明

• 操作系统: Windows10 ;
• 编程语言: Java ;
• JDK 版本: 1.8 ;
• Java IDE: IntelliJ IDEA 2020.2 x64 ;
• 使用说明:

  • 测试用例设计说明

1.总体设计说明

本程序将通过一次从初始化程序到创建进程,再到多次的单步执行进程和最后的自动化执行进程的过程以及其中会穿插阻塞当前进程和释放被阻塞的当前的进程的过程来展示这一整个完整的进程状态迁移过程。

2.PCB结构的设计

PCB结构的设计应包括:进程标识符、进程名、当前状态(“就绪”,“阻塞”,“执行”和“消亡”)、要求运行的时间片数、优先级数。

3.模拟过程设计

采用优先数调度算法对进程进行调度,每个进程可有四个状态,即:“就绪”,“阻塞”,“执行”和“消亡”。并假设初始状态为就绪状态。

为了便于处理,应该随机地赋予所有进程各自的“优先级”和“要求运行的时间片数”, 由用户给定程序中共有3个队列:就绪队列,阻塞队列和消亡队列。

在优先数算法中,进程每运行一次,优先级降低一位,要求的时间片数减1,如果要求的时间片数为零了,则将其加入消亡队列。否则,将其按照优先级的次序重新加入就绪队列。

进程运行过程中,遇到阻塞时,将该进程加入阻塞队列。(通过随机函数得到随机数,满足某种情况则使之加入到阻塞队列,或人为设置是否阻塞)每执行一次时间片后,如果阻塞队列有进程,则随机确定是否将阻塞队列中的队头进程唤醒至就绪队列(通过随机函数得到随机数,满足某种情况则使之加入到就绪队列,或人为设置是否唤醒,且唤醒的进程根据优先级放入就绪队列相应位置中)重复调度,直到就绪队列中所有进程全部运行结束。

4.输入和输出

(1)输入

进程数以及每个进程的标识符(按顺序数字编号)、进程名、当前状态(默认为“就绪”)、要求运行的时间片数、优先级数。

(2)输出(两种形式)

a)在输入某个时间片的情况下,输出每个队列里进程的信息,和正在执行的进程的信息;

b)输出各个时刻每个队列里进程的信息,和正在执行的进程的信息。

  • 结果测试情况

1.初始化

点击初始化按钮,初始化整个程序,初始化成功之后会弹出相应的提示;

若不在初始化的情况下,点击其他按钮也会给出提示,要求用户初始化之后再使用,例如:再没有初始化的情况下点击创建进程的按钮(任何不按照所指定的要求进行的非法操作,本程序均做了边界限定和友情提示,之后的演示不再一一赘述)。

2.创建进程

在输入进程名的文本框(文本框不能为空,进程名可以重名,因为本程序会为每一个被创建进程名设置一个专属的Tag,Tag不重复且唯一,Tag是程序自动生成的不需要用户关心)中输入进程名,并点击创建进程的按钮,创建进程;

重复上述操作依次创建每个进程,被创建的进程,会被默认加到就绪队列中。

3.单步执行

点击执行一次按钮,查看执行效果,程序会显示执行一次进程调度的实时过程以及队列的实时信息(关于HPF算法,本程序使用Java中的优先队列来实现的,优先队列(也就是就绪队列,其他队列都是普通队列)的实现是一个小端堆,任何进程每一次放入优先队列中,都会比较其和队列中的优先级,将优先级最大的放在堆首,也就是队列的队头,确保每一次从队列中取出的进程都是优先级最高的)。

4.自动化执行

点击自动化执行按钮,查看执行效果,程序会自动执行进程调度,直到所有进程的时间片数为0,也就是直到就绪队列为空,消亡的进程被加入到死亡队列。

5.阻塞当前进程和释放当前被阻塞的进程

在单步执行的过程中,点击阻塞当前进程按钮,阻塞下个即将运行的进程(进程只有在运行时才会因阻塞被加入到阻塞队列);

阻塞当前进程按钮的监听器会将就绪队列的队首的进程的状态位status赋值为-1,也就是将下一个即将运行的进程状态改成阻塞状态,再下一次运行中,该进程会因此阻塞,并被加入到阻塞队列中;

在自动化执行的过程中,点击阻塞当前进程,会阻塞当前正在执行的进程,并将其加入到阻塞队列中(自动化执行过程中和单步执行过程中关于阻塞进程的区别在于单步执行过程中的阻塞进程体现不出来瞬发性,因为阻塞进程的过程被拆解了,而自动化执行过程中阻塞进程的过程是瞬发的,更符合逻辑,其实两者阻塞进程过程的本质和逻辑是无差的);


关于释放当前被阻塞的进程,就是从阻塞队列中拿出一个被阻塞的进程,修改其状态为就绪状态,并放入就绪队列中,释放当前被阻塞的进程的按钮也是可以被多次调用的(前提是阻塞队列中还有阻塞进程),释放当前被阻塞的进程不管是单步执行还是自动化执行都是没差的,没有需要特别注意的事项。

在自动化执行过程,阻塞当前进程与释放当前被阻塞进程也是可以直接操作的。

  • 作者:江南煮酒
  • 原文链接:https://blog.csdn.net/qq_40100414/article/details/113816164
    更新时间:2022-09-28 14:17:57