需求分析:
本程序旨在模拟单处理器系统中的进程调度,实现时间片轮转、优先数、最短进程优先和最短剩余时间优先四种调度算法。程序将模拟进程创建、就绪队列管理以及调度过程,并输出相关信息以验证调度算法的正确性。
(1)输入的形式和输入值的范围;
无。
(2)输出的形式;
当前运行进程的标识符、优先数、剩余运行时间信息
调度后就绪队列中进程的标识符、优先数、剩余运行时间等信息
(3)程序所能达到的功能;
组织进程:
定义进程控制块(PCB)结构体,包含进程标识符、优先数、剩余运行时间信息。创建就绪队列,用于存储等待调度的进程。
创建进程:
接收用户输入的进程数量、标识符、优先数和初始运行时间。为每个进程分配PCB,并填写相关信息。将新创建的进程挂入就绪队列。
实现四种调度算法:
时间片轮转调度:按照进程在就绪队列中的顺序依次运行,每个进程运行一个时间片后切换到下一个进程。
优先数调度:选择优先数最高的进程运行。
最短进程优先:选择初始运行时间最短的进程运行。
最短剩余时间优先:选择剩余运行时间最短的进程运行。
在每次调度时,输出当前运行进程的PCB信息以及调度后就绪队列的状态。
测试数据:(随机生成)
概要设计:
(1)抽象数据类型(ADT)定义
PCB(进程控制块)
pid:整数类型,表示进程标识符。
priority:整数类型,表示进程的优先数,数值越小表示优先级越高。
remaining_time:整数类型,表示进程的剩余运行时间。
Scheduler(调度器)
ready_queue:PCB对象列表,表示就绪队列。
run_pcb:PCB对象,指向当前正在运行的进程控制块。
time_slice:整数类型,表示时间片长度。
(2)主程序的流程
初始化调度器对象(Scheduler),设定时间片长度。
调用调度器的create_processes方法创建指定数量的进程,并将它们加入就绪队列。
调用相应的调度算法(SJF、SRTF、其他调度算法),选择就绪队列中的进程执行。
如果当前进程执行完毕(remaining_time为0),则从就绪队列中移除该进程。
如果当前进程未执行完毕,但时间片耗尽,则将当前进程放回就绪队列,并更新其剩余时间。
重复步骤3至5,直到就绪队列为空。
(3)各程序模块之间的层次 (调用)关系
主程序
初始化Scheduler对象。
调用Scheduler对象的create_processes方法创建进程。
调用Scheduler对象的调度算法方法(如shortest_job_first、shortest_remaining_time_first等)进行进程调度。
Scheduler类
维护就绪队列(ready_queue)和当前运行进程(run_pcb)。
提供创建进程(create_processes)和进程调度(如shortest_job_first、shortest_remaining_time_first等)的方法。
PCB类
表示进程控制块,包含进程的基本信息(pid、priority、remaining_time)。
提供__str__方法用于打印进程信息。
调用关系图:
概要设计
实现概要设计中定义的所有数据类型,对每个操作只需要写出伪码算法;对主程序和其他模
块也都需要写出伪码算法;画出函数的调用关系图。
伪码算法:
1.PCB 类:
初始化(pid, priority, remaining_time):
设置 pid 为进程标识符
设置 priority 为进程优先数
设置 remaining_time 为剩余运行时间
转换为字符串():
返回 PCB 的字符串表示形式
2.Scheduler 类:
初始化(time_slice=2):
设置就绪队列 ready_queue 为空列表
设置正在运行的 PCB 指针 run_pcb 为 None
设置时间片长度 time_slice
创建进程(num_processes):
对于 i 从 0 到 num_processes-1:
pid = i + 1
priority = 生成 1 到 10 之间的随机整数
remaining_time = 生成 1 到 5 之间的随机整数
创建 PCB 实例 pcb,参数为 pid, priority, remaining_time
将 pcb 添加到 ready_queue
打印 "创建进程: " 和 pcb 的字符串表示
时间片轮转调度算法
round_robin(self):
打印 "时间片轮转调度算法(quantum=" + 字符串表示(self.time_slice) + ")"
当 ready_queue 不为空时执行:
取出 ready_queue 的第一个 PCB 赋值给 run_pcb
打印 "运行: " + 字符串表示(run_pcb)
如果 run_pcb 的剩余时间 remaining_time 大于 0:
run_pcb 的剩余时间减去时间片长度
如果剩余时间小于 0,则将其设置为 0
打印 " 剩余时间: " + 字符串表示(run_pcb.remaining_time)
如果剩余时间仍大于 0,将 run_pcb 放回 ready_queue 的末尾
打印 "所有进程都已终止"
优先数调度算法
priority_scheduling(self):
打印 "优先数调度算法"
当 ready_queue 不为空时执行:
对 ready_queue 按优先级升序排序
取出 ready_queue 的第一个 PCB 赋值给 run_pcb
打印 "运行: " + 字符串表示(run_pcb)
当 run_pcb 的剩余时间 remaining_time 大于 0 时执行:
run_pcb 的剩余时间减去 1
打印 " 剩余时间: " + 字符串表示(run_pcb.remaining_time)
打印 "所有进程都已终止"(这里的位置可能不恰当,通常应在所有进程运行完后打印)
最短进程优先调度算法(SJF)
shortest_job_first(self):
打印 "最短进程优先调度算法"
当 ready_queue 不为空时执行:
对 ready_queue 按剩余时间升序排序
取出 ready_queue 的第一个 PCB 赋值给 run_pcb
打印 "运行: " + 字符串表示(run_pcb)
将 run_pcb 的剩余时间设置为 0(假设连续运行到完成)
打印 "所有进程都已终止"
shortest_remaining_time_first():
当 ready_queue 不为空时:
从 ready_queue 中选择剩余时间最短的 PCB
从 ready_queue 中移除该 PCB
将 PCB 设置为当前运行 PCB
打印 "运行: " + 当前运行 PCB 的信息
如果 当前运行 PCB 的剩余时间大于 0:
当前运行 PCB 的剩余时间减 1
打印 "剩余时间: " + 当前运行 PCB 的剩余时间
如果 当前运行 PCB 的剩余时间仍大于 0:
将 当前运行 PCB 放回 ready_queue
打印 "所有进程都已终止"
程序流程:
1. 导入和初始化Schedule
2. 创建进程,使用create_processes方法创建进程。
3. 时间片轮转调度算法
4. 优先数调度算法
5. 最短进程优先调度算法
6. 最短剩余时间优先调度算法
测试运行结果:
生成的时间片、生成的进程优先数、运行剩余时间均为随机生成数。
源代码:
import random
class PCB:
def __init__(self, pid, priority, remaining_time):
self.pid = pid # 进程标识符
self.priority = priority # 进程优先数
self.remaining_time = remaining_time # 剩余运行时间
def __str__(self):
return f"PcB(pid={self.pid},priority={self.priority},remaining_time={self.remaining_time})"
class Scheduler:
def __init__(self, time_slice):
self.ready_queue = [] # 就绪队列
self.run_pcb = None # 指向正在运行进程的进程控制块指针
self.time_slice = time_slice # 时间片长度
# 创建进程
def create_processes(self, num_processes):
for i in range(num_processes):
pid = i + 1
priority = random.randint(1, 10) # 随机生成进程优先数
remaining_time = random.randint(1, 5) # 随机生成剩余运行时间
pcb = PCB(pid, priority, remaining_time)
self.ready_queue.append(pcb)
print(f"创建进程: {pcb}")
# 时间片轮转调度算法
def round_robin(self):
print(f"Time-slice Round Robin(quantum={self.time_slice}):")
while self.ready_queue:
# 取出就绪队列的第一个进程运行
self.run_pcb = self.ready_queue.pop(0)
print(f"运行: {self.run_pcb}")
# 模拟进程运行一个时间片
if self.run_pcb.remaining_time > 0:
self.run_pcb.remaining_time -= self.time_slice
if self.run_pcb.remaining_time < 0:
self.run_pcb.remaining_time = 0
print(f" 剩余时间: {self.run_pcb.remaining_time}")
# 如果剩余时间大于0,则放回就绪队列末尾
if self.run_pcb.remaining_time > 0:
self.ready_queue.append(self.run_pcb)
# 所有进程都已终止
print("所有进程都已终止")
# 优先数调度算法
def priority_scheduling(self):
print("Priority Scheduling:")
while self.ready_queue:
# 按照优先级排序就绪队列
self.ready_queue.sort(key=lambda x: x.priority)
# 取出优先级最高的进程运行
self.run_pcb = self.ready_queue.pop(0)
print(f"运行: {self.run_pcb}")
# 模拟进程运行到完成
while self.run_pcb.remaining_time > 0:
self.run_pcb.remaining_time -= 1
print(f" 剩余时间: {self.run_pcb.remaining_time}")
# 如果进程已经运行完,则不需要放回就绪队列
print("所有进程都已终止")
# 最短进程优先调度算法(SJF)
def shortest_job_first(self):
print("Shortest Job First:")
while self.ready_queue:
# 按照剩余时间排序就绪队列
self.ready_queue.sort(key=lambda x: x.remaining_time)
# 取出剩余时间最短的进程运行
self.run_pcb = self.ready_queue.pop(0)
print(f"运行: {self.run_pcb}")
# 模拟进程运行到完成
self.run_pcb.remaining_time = 0 # 因为SJF假设进程会连续运行到完成
print("所有进程都已终止")
# 最短剩余时间优先调度算法(SRTF)
def shortest_remaining_time_first(self):
print("Shortest Remaining Time First:")
while self.ready_queue:
# 选择剩余时间最短的进程
min_remaining_time_pcb = min(self.ready_queue, key=lambda x: x.remaining_time)
# 取出并运行该进程
self.ready_queue.remove(min_remaining_time_pcb)
self.run_pcb = min_remaining_time_pcb
print(f"运行: {self.run_pcb}")
# 模拟进程运行一个时间片
if self.run_pcb.remaining_time > 0:
self.run_pcb.remaining_time -= 1
print(f" 剩余时间: {self.run_pcb.remaining_time}")
# 如果剩余时间大于0,则放回就绪队列
if self.run_pcb.remaining_time > 0:
self.ready_queue.append(self.run_pcb)
print("所有进程都已终止")
# 测试
if __name__ == "__main__":
time_slice = random.randint(1, 3)
scheduler = Scheduler(time_slice)
# 创建5个进程
scheduler.create_processes(5)
# 时间片轮转调度算法
print("---时间片轮转调度算法---")
scheduler.round_robin()
print('----------重新创建进程-------------')
scheduler.ready_queue = [] # 清空就绪队列
scheduler.create_processes(5) # 重新创建5个进程
# 优先数调度算法
print("---优先数调度算法---")
scheduler.priority_scheduling()
print('----------重新创建进程-------------')
scheduler.ready_queue = [] # 清空就绪队列
scheduler.create_processes(5) # 重新创建5个进程
# 最短进程优先调度算法
print("---最短进程优先调度算法---")
scheduler.shortest_job_first()
print('----------重新创建进程-------------')
scheduler.ready_queue = [] # 清空就绪队列
scheduler.create_processes(5) # 重新创建5个进程
# 最短剩余时间优先调度算法
print("---最短剩余时间优先调度算法---")
scheduler.shortest_remaining_time_first()