📜  SJF 完整表格(1)

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

SJF 完整表格

简介

SJF(Shortest Job First)是一种常用的进程调度算法,也称为最短作业优先算法。其选择最短作业优先执行,可以使CPU资源得到最优的利用。SJF算法可以分为两种类型:非抢占式和抢占式。非抢占式的SJF算法在进程开始执行时选取最短的作业,直到该作业执行完毕才会选取下一个作业。抢占式的SJF算法则允许更短的作业在执行时中断更长的作业,并开始执行更短的作业,这可能会导致更长的作业出现饥饿现象(一直无法被执行)。

完整表格

下表是SJF算法的完整表格:

| 进程ID | 到达时间 | 服务时间 | 开始时间 | 完成时间 | 周转时间 | 带权周转时间 | | ------ | -------- | -------- | -------- | -------- | -------- | ------------ | | P1 | 0 | 5 | 0 | 5 | 5 | 1.00 | | P2 | 1 | 3 | 5 | 8 | 7 | 2.33 | | P3 | 2 | 1 | 8 | 9 | 7 | 7.00 | | P4 | 3 | 2 | 9 | 11 | 8 | 4.00 | | P5 | 4 | 4 | 11 | 15 | 11 | 2.75 |

在上表中,每个进程的到达时间、服务时间、开始时间、完成时间、周转时间和带权周转时间均已经列出。其中,

  • 到达时间:指进程进入就绪队列的时间;
  • 服务时间:指进程需要的CPU执行时间;
  • 开始时间:指进程开始执行的时间;
  • 完成时间:指进程完成执行的时间;
  • 周转时间:指进程运行时间和就绪时间的总和;
  • 带权周转时间:指周转时间和服务时间的比值。
实现

SJF算法的实现过程一般包括以下步骤:

  1. 将进程按到达时间的先后顺序加入就绪队列。
  2. 从就绪队列中选取服务时间最短的进程开始执行,更新进程的开始时间。
  3. 进程执行完毕后,更新进程的完成时间以及所有其他进程的开始时间。
  4. 重复第2、3步,直到所有进程都执行完毕。

以下是SJF算法的实现代码:

from operator import itemgetter

def sjf(processes):
    processes.sort(key=itemgetter(1, 2))  # 将进程按到达时间和服务时间排序
    n = len(processes)  # 进程总数
    start_times = [None] * n  # 开始时间
    finish_times = [None] * n  # 完成时间
    response_times = [None] * n  # 响应时间
    turn_around_times = [None] * n  # 周转时间
    total_time = 0  # 总运行时间
    ready_queue = []  # 就绪队列
    i = 0  # 当前进程的下标
    t = 0  # 当前时间
    while i < n or ready_queue:
        while i < n and processes[i][1] <= t:
            ready_queue.append(processes[i])
            i += 1
        if not ready_queue:
            t += 1
            continue
        ready_queue.sort(key=itemgetter(2))  # 将就绪队列按服务时间排序
        next_process = ready_queue.pop(0)
        start_time = max(t, next_process[1])
        start_times[next_process[0]] = start_time
        response_times[next_process[0]] = start_time - next_process[1]
        t = start_time + next_process[2]
        finish_times[next_process[0]] = t
        turn_around_times[next_process[0]] = t - next_process[1]
        total_time += t
    print("平均周转时间:", total_time / n)
    print("平均带权周转时间:", sum([turn_around_times[i] / processes[i][2] for i in range(n)]) / n)
    
# 使用样例
processes = [
    [0, 5],
    [1, 3],
    [2, 1],
    [3, 2],
    [4, 4],
]
sjf(processes)
总结

SJF算法能够使CPU资源得到最优的利用,但在实际应用中很难确定进程的服务时间,因此SJF算法往往只能作为一种理想状态下的算法参考。此外,抢占式的SJF算法需要更加复杂的实现,而且会导致更长的作业出现饥饿现象,因此应该根据实际情况选择合适的算法。