赞
踩
资源下载地址:https://download.csdn.net/download/sheziqiong/85932347
资源下载地址:https://download.csdn.net/download/sheziqiong/85932347
操作系统是计算机系统配置的基本软件之一。它在整个计算机系统软件中占有中心地位。其作用是对计算机系统进行统一的调度和管理,提供各种强有力的系统服务,为用户创造既灵活又方便的使用环境。本课程是计算机及应用专业的一门专业主干课和必修课。
通过课程设计,使学生掌握操作系统的基本概念、设计原理及实施技术,具有分析操作系统和设计、实现、开发实际操作系统的能力。
提交一批作业(>=10),按先来先服选择一部分作业(最多 5 个)进入内存
为每个作业创建一个进程,并分配内存(用户内存:0—1024K,采用可变连续分配方式)
进程调度功能(时间片轮转)
随机阻塞进程,并在一段时间后唤醒进程(选做)
显示相关信息:后备作业队列、内存分配情况、进程信息、完成作业情况
这些功能要有机地连接起来
软件:Windows 10, JDK1.8,IntelliJ IDEA
硬件:Intel® Core™ i5-8300H , 2.30GHz, RAM: 8.00GB
本次课程设计是将作业调度,内存管理、进程调度、进程阻塞等功能有机结合起来的一道题目。首先,需要使用随机数初始化 10 个作业,放入后备队列中,然后使用先来先服务(FCFS)进行作业调度,使用时间片轮转算法进行进程调度。其中,最多只能有五个作业能同时进入内存,本实验假设阻塞状态的进程依然在内存中。也就是说,处于就绪、运行、阻塞三种状态的进程数目之和最多为 5 个,即并发进程数最多为 5 个,在进程结束后,就会被调出内存,使用 FCFS 算法从后备队列中调入新的作业。在内存中的几个非阻塞状态的进程使用时间片轮转(RR)算法进行调度。而作业在进入内存之前,是要申请内存的,这时使用首次适应(FF)算法申请内存,从空闲分区链中找到合适的空闲分区并分配给该进程。在进程结束时,要回收其占用的内存,并进行相应的空闲分区合并。如此,便可以将作业调度、内存管理、进程调度和进程阻塞与唤醒这几个功能有机地连接起来了。
2.算法流程图:
3.项目工程截图:
/ * 调度方法 * @throws InterruptedException */ public void dispatch() throws InterruptedException { if (isFinishALLProcess()) { return; } long now = System.currentTimeMillis(); double passedTime = (now - lastTime) / 1000.0; //距离上次调度经过的时间 double allTime = (now - beginTime) / 1000.0; // 从后备队列调入进程 getNextOnDisk(allTime); if (runningIndex != -1) { double oldhasUsedTime = pcb[runningIndex].hasUsedTime; if (passedTime >= timeSlice) { if (oldhasUsedTime + passedTime >= pcb[runningIndex].needTime) { pcb[runningIndex].hasUsedTime = pcb[runningIndex].needTime; pcb[runningIndex].status = "Finish"; releaseMemory(pcb[runningIndex].address); } else { pcb[runningIndex].hasUsedTime = oldhasUsedTime + timeSlice; pcb[runningIndex].status = "Waiting"; } // 从就绪队列中选择下一个进程 int next = getNextWaiting(runningIndex); if (next != -1) { pcb[next].status = "Running"; runningIndex = next; print(); } } } else { pcb[0].status = "Running"; runningIndex = 0; print(); } // 随机阻塞进程 Random random = new Random(); int randomNum = random.nextInt(3); // 符合此条件的进程将被阻塞 if (randomNum == 2 && (blocked == 0 ) ) { blockIndex = runningIndex; pcb[runningIndex].status = "Blocking"; blocked = 1; runningIndex = getNextWaiting(runningIndex); } // 唤醒进程 if (blocked == 1) { long time = System.currentTimeMillis(); double intervalTime = (time - lastTime) / 1000.0; if (runningIndex == -1) { // 只剩下最后一个阻塞进程未执行完,则该进程休眠1秒后唤醒 Thread.sleep(1000); runningIndex = blockIndex; pcb[runningIndex].status = "Waiting"; blocked = 0; } else if (intervalTime > 2.0) { // 有进程属于阻塞状态时,满足阻塞时间大于2s则唤醒进程 if (blockIndex != -1) { pcb[blockIndex].status = "Waiting"; blocked = 0; } } } }
// 界面输出函数
6.运行结果截图(内容太多,仅展示关键部分):
初始的分区说明表(1024KB 的内存):
开始时,后备队列中的十个作业:
按照要求开始进程调度,按照时间片轮转算法:
此时,已经运行完一些进程了:
直至所有进程运行完成:
7.运行结果的分析:
第一张图是初始时候的内存分区说明表,共1024KB,都是空闲状态。
第二张图是随机生成的十个作业。第三张图开始是进程调度,此时只有 P1 到达,因此先调入内存。运行到第四张图时,P1、P2、P10、P9、P7 已经被进入内存,剩下 P3、P4、P5、P6、P8 在后备队列中。结合第四第五张图看,可以看出,进程调度算法是时间片轮转算法,每个时间片为 2。
在同一张图片中,结合内存分区表来看,可以看到,内存分区表中状态为 Busy 的块和 PCB 信息相符合。PCB 表中的 运行中(Running)、就绪(Waiting)、阻塞(Blocking)状态的进程刚好和内存分区表中的 Busy 状态内存块一一对应。因为最多同时调入五个作业进内存,因此,内存分区表中也最多只有五个处于 Busy 状态的内存块。
当某一个进程执行完成,就会释放内存,如果释放的内存块的前后内存块也是空闲的,则进行合并,从最后一张图可以看到,最终虽有进程都执行完毕后,内存分区表最终也回到了最初的时候,只有一个 1024KB 的空闲块。
随机阻塞进程,从第四张图片开始看,会看到有进程属于阻塞状态,当阻塞到达一定的时间后会被唤醒,最终全部执行完成。
资源下载地址:https://download.csdn.net/download/sheziqiong/85932347
资源下载地址:https://download.csdn.net/download/sheziqiong/85932347
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。