进程调度算法的实现
- 先来先服务的调度算法:最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。所以FCFS的核心点就是:我们要根据作业的到达时间以及运行时间来对作业进行安排,这样就能做到让先到达的任务被系统先服务。
- SJF调度算法:短作业(进程)优先调度算法SJF,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。
实例所示的进程执行表分别采用先到先服务和短作业优先(非抢占式)进程调度算法的调度
| 进程 | 到达时间 | 执行时间 |
|---|---|---|
| P1 | 0.0 | 9 |
| P2 | 0.4 | 4 |
| P3 | 1.0 | 1 |
| P4 | 5.5 | 4 |
| P5 | 7 | 2 |
代码实现:
- 定义进程PCB就绪队列类PCBQueue。该类设置一个表示PCB就绪队列的属性字段pcbqueue,默认为空列表。围绕pcbqueue设计入队、出队、按进程到达时间降序排序、判断队列为空、依当前时间获得队列中剩余的进程、输出队列中进程的相关信息这6种函数。
# 进程PCB
class PCB:
def __init__(self):
self.name = 0 # 进程号
self.atime = 0.0 # 到达时间
self.runtime = 0.0 # 运行时间
self.ftime = 0.0 # 完成时间
self.total = 0.0 # 周转时间
self.weight = 0.0 # 带权周转时间
# 进程PCB就绪队列
class PCBQueue:
def __init__(self):
self.pcbqueue = [] # 进程PCB就绪队列,默认为空
def EnQueue(self, pcb:PCB): # 入队
self.pcbqueue.append(pcb)
def DeQueue(self): # 出队
return self.pcbqueue.pop()
def SortQueue(self):
self.pcbqueue.sort(reverse=True, key=lambda p:p.atime)
def printQueue(self):
for p in self.pcbqueue:
print('进程', p.name, '到达时间', p.atime, '运行时间', p.runtime)
def isEmpty(self):
return not self.pcbqueue
def getSubQueue(self, curtime):
subqueue = []
for p in self.pcbqueue:
if p.atime <= curtime:
subqueue.append(p)
self.pcbqueue.remove(p)
return subqueue
def FCFS(pcbqueue: PCBQueue, m):
curtime = 0.0 # 模拟系统当前运行时间
weitime = 0.0 # 所有进程的周转时间
totime = 0.0 # 所有进程的周转时间
while(pcbqueue.isEmpty() is False):
pcb = pcbqueue.DeQueue()
pcb.ftime = curtime + pcb.runtime
curtime = curtime + pcb.runtime
pcb.total = pcb.ftime - pcb.atime
pcb.weight = pcb.total / pcb.runtime
weitime = weitime + pcb.weight
totime = totime + pcb.total
print('进程%s,到达时间:%.2f,运行时间:%.2f,完成时间:%.2f,周转时间:%.2f,带权周转时间%.2f'%(
pcb.name, pcb.atime, pcb.runtime, pcb.ftime, pcb.total, pcb.weight))
print("%s个进程的平均周转时间为%.2f" % (m, totime / m))
print("%d个进程的平均带权周转时间为%.2f" % (m, weitime / m))
def SJF(pcbqueue: PCBQueue, m):
curtime = 0.0 # 模拟系统当前运行时间
weitime = 0.0 # 所有进程的带权周转时间
totime = 0.0 # 所有进程的周转时间
while(pcbqueue.isEmpty() is False):
subqueue = pcbqueue.getSubQueue(curtime)
subqueue.sort(reverse=True, key=lambda p: p.runtime)
while (subqueue):
pcb = subqueue.pop()
pcb.ftime = curtime + pcb.runtime
curtime = curtime + pcb.runtime
pcb.total = pcb.ftime - pcb.atime
pcb.weight = pcb.total / pcb.runtime
weitime = weitime + pcb.weight
totime = totime + pcb.total
print('进程%s,到达时间:%.2f,运行时间:%.2f,完成时间:%.2f,周转时间:%.2f,带权周转时间%.2f' % (
pcb.name, pcb.atime, pcb.runtime, pcb.ftime, pcb.total, pcb.weight))
print("%s个进程的平均周转时间为%.2f" % (m, totime / m))
print("%d个进程的平均带权周转时间为%.2f" % (m, weitime / m))
if __name__ == '__main__':
pcbqueue = PCBQueue()
t_list = [['P1', 0.0, 9], ['P2', 0.4, 4], ['P3', 1.0, 1], ['P4', 5.5, 4], ['P5', 7.0, 2]]
for t in t_list:
pcb = PCB()
pcb.name = str(t[0])
pcb.atime = float(t[1])
pcb.runtime = float(t[2])
pcbqueue.EnQueue(pcb)
pcbqueue.SortQueue()
a = input('输入操作序号(0:FCFS,1:SJF,-1:EXIT):')
if a == '0':
print('先来先服务运行结果:')
FCFS(pcbqueue, 5)
elif a == '1':
print('非抢占式短作业优先运行结果:')
SJF(pcbqueue, 5)
elif a == '-1':
exit(0)
else:
print('非法输入')
exit(1)

本文深入探讨了两种常见的进程调度算法——先来先服务(FCFS)与短作业优先(SJF),并提供了这两种算法的具体实现代码。通过实例展示,帮助读者理解如何根据不同进程的到达时间和运行时间来优化调度策略。

被折叠的 条评论
为什么被折叠?



