ljqcore / os_exam

进程管理与内存分配模拟程序

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

os_exam

进程管理与内存分配模拟程序

实验目的

  • 设计编写OS进程与内存管理模拟程序,模拟OS进程的创建、阻塞、唤醒、撤销等进程控制以及OS内存管理方法和过程,加深操作系统进程控制原语主要任务和过程的理解,加深操作系统内存分配的基本策略,加深操作系统以进程为核心的完整架构的理解。
  • 提高综合性实验的分析、设计及编程实现能力。

实验内容

设计一个OS进程与内存管理模拟程序,要求:

  1. 程序运行后提供一个交互界面或窗口,允许用户输入以下命令并可以滴对命令进行解释执行,
    • creatproc:提交作业命令,要求用户提供作业估计运行时长和内存大小需求。该命令的解释执行过程为对该作业创建对应的进程,完成PCB建立、存储空间分配等工作。(既执行OS的创建进程原语)
    • killproc 进程号:终止进程命令。该命令的解释执行过程为对进程进行撤销,回收存储空间和PCB。
    • iostrartproc 进程号:阻塞进程命令。该命令的解释执行过程为对处于运行状态的进程进行阻塞操作,进程状态转为阻塞状态。
    • iofinishproc 进程号:阻塞进程命令。该命令的解释执行过程为对处于阻塞状态的进程进行唤醒操作,进程状态转为就绪状态。
    • psproc:显示所有进程状态命令。该命令的解释执行过程为显示出所有进程的状态信息,主要包括进程id,进程状态,存储空间地址。
    • mem:显示内存空间使用情况信息。该命令的解释执行过程为显示内存空间的占用和空闲情况。
  2. 设计思路提示:内存空间可用数组模拟,主要原语模拟实现,包括创建进程,终止进程,阻塞进程,唤醒进程,进程调度等原语。进程调度算法可选择 FCFS、RR、SJF中任意一种。内存分配可选择可变分区策略或页式内存分配方案中任意一种。
  3. 程序设计语言不限。

选取实验文档部分内容

需求分析

(一)主存空间的分配和回收 首先内存空间应划分为两个部分,第一个部分模拟存储操作系统的内核空间;第二个部分就是用户空间,这是用户应用程序运行的空间,用来存储进程。 采用可变分区策略和首次适应算法进行内存分配。可变分区就是物理块可以被划分为多个大小不一的可用分区,然后首次适应算法就是从低地址开始查找可用分区,直到找到第一个足够大的分区为止。 主存空间的回收分为四种情况:

  • 上一块和下一块没有空闲的分区,不用合并
  • 上一块空闲,合并上一块分区
  • 下一块空闲,合并下一块分区
  • 上下都空闲,合并上下两块分区

(二)抢占式优先权调度算法 在CPU调度进程的时候,选取优先级最高的进程调度到CPU中;如果优先级相同的话,那么就按照先来先服务的算法进行调度。 但在这个调度的过程中,如果是独立进程,那就可以直接被调度到CPU中。如果它是有前驱的,那么就要等待前驱进程完成之后,才能被调度到CPU中。

(三)动态优先级的设置 在整个进程的调度中,在进程被调度后,如果时间片用完进程都还未结束,那么就将这个进程的优先级减一。

(四)双CPU的设计 设置两个CPU,CPU1和CPU2,CPU1的优先级高于CPU2,也就是说会优先选择CPU1来运行,CPU1中是优先级最高的进程,CPU2中是优先级第二的进程,运行完一个时间片后,优先权-1,运行时间-1,再重新寻找优先级第一第二的进程运行。当进程的运行时间为0时,结束运行,进入完成队列。

(五)四个队列的设置 在此进程模拟程序中,根据进程的调度划分了四个队列:后备队列,就绪队列,阻塞队列和完成队列。其中,后备队列属于外存,创建好的进程直接放进后备队列,等待被调入到内存;就绪队列根据先来先服务调入后备队列中的进程,分配内存,并且进行优先级的排序;阻塞队列主要存放前驱进程未完成的子孙进程或者是手动阻塞的进程,也是属于内存;完成队列存放已经运行完成的进程,属于外存。

具体设计

(一)PCB 分配PCB的资源:进程号Pid(判断不允许重复),优先级Priority,运行时间RequiredTime,前驱节点Pre,占用内存大小Memory,进入CPU的序号。

(二)道数 设置系统从外存能调入内存的最大进程数channel(道数)为4;

(三)CPU时间片调度 设置每次CPU调度给进程的时间片大小为5;

(四)存储进程状态的容器

private ArrayList<PCB> reserveList = new ArrayList<PCB>();  // 后备队列
private ArrayList<PCB> readyList = new ArrayList<PCB>();   // 就绪队列
private ArrayList<PCB> hookList = new ArrayList<PCB>();    // 阻塞队列
private ArrayList<PCB> endList = new ArrayList<PCB>();     // 终止队列
private PCB[] cpuList = new PCB[2];                       // 两个CPU处理机

(五)内存存储

private final int memorySize=256;
private final int osSize=32;
private int[] memoryList = new int[memorySize];
其中,osSize模拟的是操作系统的核心态;memorySize设置内存大小;memoryList 用来存储内存空间;

(六)内存分配 由于采用数组来存储内存空间,使用Java绘图来画出进程在内存空间中的分布状态,所以在分配内存空间的时候,使用首次适应算法,从低地址开始遍历,找到一块够长的空闲区,然后将进程号和内存大小分别存进去,示意图如下:

(七)内存回收 由于上列内存分配图,我们在回收内存的时候,直接将存储Pid和Memory的位置置为0,表示内存的空闲。

(八)创建原语 通过JTextField来设置五个输入栏,分别存储进程号Pid,优先级Priority,运行时间RequiredTime,前驱节点Pre(如果不输入前驱,设置前驱为-1,表示此为独立进程),占用内存大小Memory。创建好进程后,将进程添加到后备队列中。

(九)阻塞原语 点击CPU处理机调度的进程号,程序会自动将正在被调度的进程添加到阻塞队列中。

(十)唤醒原语 点击阻塞队列中的进程后,进程会自动进入就绪队列,等待被调度分配。

(十一)终止原语 点击就绪队列,后备队列和阻塞队列中的进程后,释放进程的PCB和内存分配情况(如果是终止后备队列的进程,则不需要释放内存)

(十二)进程调度 当创建符合规定的进程后,进程自动被添加到后备队列中;通过系统设置的最大道数和内存区的分配,将后备队列中的进程调入到就绪队列,同时通过优先级高低排序,对进程进行排序。同时将前驱结点还未完成的子孙进程调入阻塞队列中,如果前驱结点完成,那么子孙进程又被重新调入到就绪队列中。然后选取优先级最高的进程进入CPU运行,如果在一个时间片内运行结束,那么就进入完成队列;如果在一个时间片内还未运行结束,优先级减一,同时判断就绪队列中是否有优先级更高的进程抢占此调度机。 当阻塞一个进程时,进程会进入阻塞队列;当唤醒一个进程时,进程会进入就绪队列;当终止一个进程时,要释放进程的PCB和内存的分配。

About

进程管理与内存分配模拟程序


Languages

Language:Java 100.0%