📜  OS SJF调度(1)

📅  最后修改于: 2023-12-03 15:03:25.646000             🧑  作者: Mango

OS SJF调度

什么是SJF调度?

SJF调度指的是最短作业优先调度算法(Shortest Job First Scheduling)。它是一种基于处理器时间片轮转实现的调度算法,通过优先选择运行时间最短的进程,可以在一定程度上提高系统的响应速度和处理能力。

SJF调度的原理

SJF调度的原理是基于进程预测的时间长度进行优先级排列。当一个进程提交到系统中时,需要对其进行处理器时间的估算。根据预测后的处理器时间长度,选择一个预估时间最短的进程先执行。

SJF调度的优缺点

SJF调度的优点在于可以最大化利用CPU处理性能,实现系统的高响应速度。然而,由于它是一种基于预测的算法,对于预估时间较长的进程来说,会对系统造成较大的影响,导致长作业饥饿(Long job starvation)问题,从而影响系统的正常运行。

SJF调度的实现

SJF调度算法的实现分为两种:

  1. 非抢占式SJF调度:在进程提交到系统后进行预估,将其加入就绪队列中,直到其运行完毕或等待I/O操作等中断事件的发生。由于它是一种非抢占式算法,不能够中途暂停正在运行的进程,不能够有效处理长时间运行的进程,可能会导致长作业饥饿的问题。

  2. 抢占式SJF调度:在非抢占式算法的基础上,增加了当新进程进入系统时,先比较其预估的运行时间与正在运行的进程运行时间的长度,若新进程的预估时间更短,则需要将正在运行的进程暂停,并切换到新进程上,以实现更为高效的调度。

SJF调度的实例及代码实现

下面是一个基于Python的SJF调度算法实现:

import operator

# 进程类
class Process(object):

    def __init__(self, process_id, burst_time):
        self.process_id = process_id
        self.burst_time = burst_time
        self.waiting_time = 0
        self.turnaround_time = 0

    # 执行进程
    def execute(self):
        self.burst_time -= 1

    # 获取剩余运行时间
    def get_remaining_time(self):
        return self.burst_time

    # 获取等待时间
    def get_waiting_time(self):
        return self.waiting_time

    # 获取周转时间
    def get_turnaround_time(self):
        return self.turnaround_time

    # 更新等待时间和周转时间
    def update_time(self, increment):
        self.waiting_time += increment
        self.turnaround_time += increment

# SJF调度
def sjf(process_list):

    total_waiting_time = 0
    total_turnaround_time = 0
    current_time = 0

    # 将进程按照执行时间排序
    process_list = sorted(process_list, key=operator.attrgetter('burst_time'))

    while process_list:
        # 获取执行时间最短的进程
        current_process = process_list.pop(0)
        # 执行进程
        for i in range(current_process.burst_time):
            current_time += 1
            current_process.execute()
            # 更新等待时间和周转时间
            for process in process_list:
                process.update_time(1)
            # 如果有新的进程到达,将其加入等待列表中
            new_processes = [p for p in process_list if p.get_waiting_time() <= current_time]
            process_list = list(set(process_list) - set(new_processes))
            for p in new_processes:
                process_list.insert(0, p)
            # 如果执行时间已经到达,更新等待时间和周转时间,执行下一个进程
            if current_process.get_remaining_time() == 0:
                current_process.update_time(current_time - current_process.get_waiting_time())
                total_waiting_time += current_process.get_waiting_time()
                total_turnaround_time += current_process.get_turnaround_time()
                break

    # 计算平均等待时间和平均周转时间
    n = len(process_list)
    average_waiting_time = float(total_waiting_time) / n
    average_turnaround_time = float(total_turnaround_time) / n

    return (average_waiting_time, average_turnaround_time)


if __name__ == '__main__':
    processes = [Process(1, 6), Process(2, 8), Process(3, 7), Process(4, 3)]
    sjf_result = sjf(processes)
    print("SJF Average Waiting Time: ", sjf_result[0])
    print("SJF Average Turnaround Time: ", sjf_result[1])

上面的代码实现了一个SJF调度算法,输入的是一个进程列表,输出的是平均等待时间和平均周转时间。可以通过更改进程的执行时间,在不同的场景下测试该算法的效果。