操作系统进程调度算法

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

进程调度算法的实现

  1. 先来先服务的调度算法:最简单的调度算法,既可以用于作业调度 ,也可以用于程序调度,当作业调度中采用该算法时,系统将按照作业到达的先后次序来进行调度,优先从后备队列中,选择一个或多个位于队列头部的作业,把他们调入内存,分配所需资源、创建进程,然后放入“就绪队列”,直到该进程运行到完成或发生某事件堵塞后,进程调度程序才将处理机分配给其他进程。所以FCFS的核心点就是:我们要根据作业的到达时间以及运行时间来对作业进行安排,这样就能做到让先到达的任务被系统先服务。
  2. SJF调度算法:短作业(进程)优先调度算法SJF,是指对短作业或短进程优先调度的算法。它们可以分别用于作业调度和进程调度。短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行。而短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。

实例所示的进程执行表分别采用先到先服务和短作业优先(非抢占式)进程调度算法的调度

进程到达时间执行时间
P10.09
P20.44
P31.01
P45.54
P572

代码实现:

  1. 定义进程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)

实现输出

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵星人来踩博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值