📅  最后修改于: 2023-12-03 15:20:09.143000             🧑  作者: Mango
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 |
在上表中,每个进程的到达时间、服务时间、开始时间、完成时间、周转时间和带权周转时间均已经列出。其中,
SJF算法的实现过程一般包括以下步骤:
以下是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算法需要更加复杂的实现,而且会导致更长的作业出现饥饿现象,因此应该根据实际情况选择合适的算法。