操作系统模拟实验—短作业调度算法(SJF)Python实现
短作业优先法
短作业优先(SJF, Shortest Job First)又称为“短进程优先”SPN(Shortest Process Next);这是对FCFS算法的改进,其目标是减少平均周转时间。
定义
对预计执行时间短的作业(进程)优先分派处理机。通常后来的短作业不抢先正在执行的作业。
SJF的特点
优点:
- 比FCFS改善平均周转时间和平均带权周转时间,缩短作业的等待时间;
- 提高系统的吞吐量;
缺点:
- 对长作业非常不利,可能长时间得不到执行;
- 未能依据作业的紧迫程度来划分执行的优先级;
- 难以准确估计作业(进程)的执行时间,从而影响调度性能。
SJF的变型
- “最短剩余时间优先”SRT(Shortest Remaining Time)(允许比当前进程剩余时间更短的进程来抢占)
- “最高响应比优先”HRRN(Highest Response Ratio Next)(响应比R = (等待时间 + 要求执行时间) / 要求执行时间,是FCFS和SJF的折衷) ——以上内容出自百度百科
实验
本次实验是基于Python3.x的环境.
# 模拟文件 (作业名字, 作业到达时间, 作业运行时间)
INPUT_DATA = [('A',1,5), ('B',4,5), ('C',2,3), ('D',10,2)]
ALL_JOB = [] # 从文件读进来的作业
ARRIVED_JOB = [] #就绪队列
import time
from math import ceil
class Job:
'''
作业实体,name名字,arrivedTime到达时间,runTime运行时间,
'''
def __init__(self, name, arrivedTime, runTime):
self.name = name
self.arrivedTime = arrivedTime
self.runTime = runTime
def run(self):
time.sleep(self.runTime)
# 从文件中读进来数据实例化
for _ in INPUT_DATA:
name, arrivedTime, runTime = _
ALL_JOB.append(Job(name, arrivedTime, runTime))
# 按段作业优先的策略对作业排序 冒泡
def RankJob():
for i in range(len(ARRIVED_JOB) - 1):
for j in range(len(ARRIVED_JOB)-1-i):
if ARRIVED_JOB[j].runTime > ARRIVED_JOB[j+1].runTime:
ARRIVED_JOB[j], ARRIVED_JOB[j+1] = ARRIVED_JOB[j+1], ARRIVED_JOB[j]
print('作业调度顺序排序完成........')
# 从就绪队列中拿来一个调度
def SchedulerJob():
print('代号为{0}作业开始运行,运行时间{1}s........'.format(ARRIVED_JOB[0].name, ARRIVED_JOB[0].runTime))
ARRIVED_JOB[0].run()
print('运行结束........')
# 执行完作业销毁
def DeleteJob(start):
print('作业已完成销毁........')
print('带权周转时间为{}........'.format(
(time.time()-start-ARRIVED_JOB[0].arrivedTime)/ARRIVED_JOB[0].runTime))
del ARRIVED_JOB[0]
print('\n')
def main(argv=None):
start = time.time()
while True:
# 控制时间,按作业到达时间作业该到达的放入到就绪队列
delta = ceil(time.time() - start)
for _ in ALL_JOB[::]:
if _.arrivedTime < delta:
ARRIVED_JOB.append(_)
ALL_JOB.remove(_)
# 如果就绪队列不为空,则开始调度
if ARRIVED_JOB != []:
RankJob()
SchedulerJob()
DeleteJob(start)
主函数main():
if __name__ == '__main__':
main()
打印结果为:
作业调度顺序排序完成........
代号为A作业开始运行,运行时间5s........
运行结束........
作业已完成销毁........
带权周转时间为1.0001710891723632........
作业调度顺序排序完成........
代号为C作业开始运行,运行时间3s........
运行结束........
作业已完成销毁........
带权周转时间为2.333710034688314........
作业调度顺序排序完成........
代号为B作业开始运行,运行时间5s........
运行结束........
作业已完成销毁........
带权周转时间为2.000418519973755........
作业调度顺序排序完成........
代号为D作业开始运行,运行时间2s........
运行结束........
作业已完成销毁........
带权周转时间为3.0014957189559937........