本文发布且更新于个人博客 https://www.xerrors.fun/Job-Scheduling-in-Multiprogramming-System/
转载请注明出处
上一篇文章已经实现了单道程序系统的作业调度模拟程序。那么这次的要求就要更加刁钻了。
作业调度算法:采用基于「先来先服务」的调度算法或「基于优先级」的作业调度算法。其余可以参考课本中的方法进行设计。对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求
核心的改变是变成了多道程序的调度系统,那么也就自然而然的带来了资源的争夺问题;
两种调度算法
先来先服务(FCFS)是按照作业到达的先后顺序来进行作业调度的。
优先级调度算法(priority-scheduling algorithm, PSA)
我们可以这样来看作业的优先级,对于先来先服务调度算法,作业的等待时间就是作业的优先级,等待时间越长,其优先级越高。对于短作业优先调度算法,作业的长短就是作业的优先级,作业所需运行的时间越短,其优先级越高。但上述两种优先级都不能反映作业的紧迫程度。而在优先级调度算法中,则是基于作业的紧迫程度,由「外部赋予」作业相应的优先级,调度算法是根据该优先级进行调度的。这样就可以保证紧迫性作业优先运行。优先级调度算法可作为作业调度算法,也可作为进程调度算法。当把该算法用于作业调度时,系统是从后备队列中选择若干个优先级最高的作业装入内存。
——摘自汤子瀛《计算机操作系统(第四版)》
从上面的说明可以看到两个算法的唯一区别就是对待优先的看法不同,放在最小堆里面来说就是比较大小的方法不一样,所以跟上个程序一样,我们采用相同的「处理逻辑」和不同的「小于运算符」
def func(jobs, method, n):
JCB.__lt__ = getLowerThan(method)
# 省略了其他部分
return None
def getLowerThan(method):
def FCFS_lt(self, other):
# 比较到达时间的大小
return self.commit_time < other.commit_time
def PSA_lt(self, other):
# 比较优先级的大小,越小代表优先级越高
return self.priority < other.priority
if method == 'FCFS':
return FCFS_lt
elif method == 'PSA':
return PSA_lt
具体实现过程
作业控制块 JCB 的数据结构
由于采用了多道程序的调度系统,所以首先对作业的类进行修改,为了实现 PSA,新增了优先级属性「priority」。
class JCB:
# 表示系统中的资源数量,其中 1 表示独占资源
srcs = np.array([3, 2, 4, 1, 3, 1])
clock = 0 # 类的时钟
def __init__(self, priority, time, srcs):
self.priority = priority
self.name = chr(ord('A') + JCB.clock) # 名称
self.time = time # 所需时间
self.status = 'Wait' # 作业的状态
self.commit_time = JCB.clock # 作业到达时间
# 所需的资源,单道程序调度用不到的
self.srcs = srcs
JCB.clock += 1 # 类的时钟 +1
初始化作业,为了写起来方便,使用了很多的单行语句,降低了部分的可读性,这里稍微解释一下
a = [ 1 if random.random() > 0.5 else 0 for i in range(len(JCB.srcs))]
# 等同于
a = []
for i in range(len(JCB.srcs)):
if random.random() > 0.5:
a.append(1)
else:
a.append(0)
初始化作业控制块 JCB
# 初始化所有 JCB
def init():
# 创建
jsb_list = [JCB(
random.randrange(1, 8), # 优先级
random.randrange