操作系统模拟实验—短作业调度算法(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........

你可能感兴趣的:(优化算法,MyCode)