题目要求
一、 实验目的
多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
二、 实验内容
1. 优先权法、轮转法
简化假设
1) 进程为计算型的(无I/O)
2) 进程状态:ready、running、finish
3) 进程需要的CPU时间以时间片为单位确定
2. 算法描述
1) 优先权法——动态优先权
当前运行进程用完时间片后,其优先权减去一个常数。
2) 轮转法
三、 流程图
四、实验要求
1. 产生的各种随机数的取值范围加以限制,如所需的CPU时间限制在1~20之间。
2. 进程数n不要太大通常取4~8个
3. 使用动态数据结构
4. 独立编程
5. 两种调度算法
实验报告
1.实验目的
多道程序设计中,经常是若干个进程同时处于就绪状态,必须依照某种策略来决定那个进程优先占有处理机。因而引起进程调度。本实验模拟在单处理机情况下的处理机调度问题,加深对进程调度的理解。
2.实验内容与要求
①实验内容
1. 优先权法、轮转法
简化假设
1) 进程为计算型的(无I/O)
2) 进程状态:ready、running、finish
3) 进程需要的CPU时间以时间片为单位确定
2. 算法描述
1) 优先权法——动态优先权
当前运行进程用完时间片后,其优先权减去一个常数。
2) 轮转法
②实验要求
1. 产生的各种随机数的取值范围加以限制,如所需的CPU时间限制在1~20之间。
2. 进程数n不要太大通常取4~8个
3. 使用动态数据结构
4. 独立编程
5. 两种调度算法
3.流程图与模块调用
4.实验分析
想要完成操作系统算法,首先要弄清楚操作系统相关的专业术语。弄清各个算法的流程和目的要求。才能模拟出相关算法的过程。
在我的理解中,
优先权算法:
①所有线程的先后序列核心是围绕优先权的权值大小。并且该优先权的大小会动态的变化,即每随着进程被调用了一次,权值减3。所以用队列(First In First Out)这种数据结构非常好。能够有效的节省空间,算法复杂度。
②优先权算法中某个线程的结束标识是还需要的时间needTime是否变为了0。所以在随机选取线程的时候要判断该线程还需不需要资源,即needTime是否为0。
③至于状态还有一点很重要的是要即使转换。当进行下一个操作要即使转换上一个线程的状态和下一个线程的状态防止状态混淆。
轮转法
①轮转法强调先进先出的拉链式顺序,而不以其他的权值作为开始/调度的先后顺序,所以普通先进先出的普通队列是解决该算法的最好方法。
②轮转法和优先权法不一样的是优先权法每次只进一个线程只执行一次。而轮转法是进一个可以执行最多是该线程可轮转的次数/轮转值(可能在中间就完成线程的释放),所以在写程序的时候每次都要判断是否已经轮转。并且到最后还要判断还是否需要调度。如果需要,再抛入队尾。
5.运行情况
①优先权算法:
②轮转法:
6.实验体会
通过本次实验,我深刻的理解了操作系统中线程资源的分配方式和进程的调度方式。操作系统实验重在理解每一个算法的意图和目的,那么就选择适当的数据结构模拟过程就可以完成相关算法了。
本次实验采用python完成,IDE是pycharm,python的queue库文件很好的支持了我在优先权算法中对队列的相关操作,python的operator库文件,很好的提供了基于类的属性按值排序的功能,这些在算法的编写过程中否起到了很大的作用。
【附】实验代码
import operator import random import queue Q = queue.Queue() # 定义队列 class PCB: def __init__(self, id, status, weight, needTime, rotelTimes): self.id = id # 进程的id self.status = status # 进程状态 self.weight = weight # 进程状态优先权重 self.needTime = needTime # 进程需要的时间片 self.rotelTimes = rotelTimes # 轮转次数 def emptyQueue(Q): # 辅助函数-清空队列 while not Q.empty(): Q.get() def priority(): # 优先权算法 emptyQueue(Q) weight = operator.attrgetter('weight') arr_pcb.sort(key=weight, reverse=True) # 按照状态优先权重的值降序排列 for index,item in enumerate(arr_pcb): if item.needTime > 0: Q.put(item) # 压入队列 if index>0: if item.status!='finish': item.status='ready' node = Q.get() node.needTime -= 1 node.weight -= 3 if node.needTime>0: node.status='running' elif node.needTime==0: node.status = 'finish' print('**********时间片到达**********') for i in arr_pcb: print(i.id, i.status, i.weight, i.needTime) def rotel(): for a,item in enumerate(arr_pcb): if item.needTime>0: item.status='running' for b,item2 in enumerate(arr_pcb): if a!=b : if item2.status=='running': item2.status = 'ready' for j in range(0,item.rotelTimes): if item.needTime > 0: item.needTime-=1 if item.needTime==0: item.status='finish' print('**********开始轮转**********') for i in arr_pcb: print(i.id, i.status, i.rotelTimes, i.needTime) N = int(input('请输入需要创建的进程数目(4-8个):')) arr_pcb = [] for i in range(0, N): status = random.randint(1, 10) # 随机生成状态优先权重 needTime = random.randint(1, 4) # 随机生成需要的时间片 rotelTimes = random.randint(1, 3) # 轮转次数 arr_pcb.append(PCB(i, 'ready', status, needTime, rotelTimes)) # 创建进程 key = input('是否采用优先权?Y/N') if key == 'Y': print('**********进程初始化**********') for i in arr_pcb: print('进程:', i.id, i.status, '状态优先权重:', i.weight, '需要时间片数:', i.needTime) priority() while not Q.empty(): priority() elif key =='N': print('**********进程初始化**********') for i in arr_pcb: print('进程:', i.id, i.status, '轮转次数:', i.rotelTimes, '需要时间片数:', i.needTime) flag=0 for item in arr_pcb: if item.needTime>0: flag=1 while flag: rotel()