refactor: 修改实验步骤

This commit is contained in:
ViperEkura 2026-04-30 15:43:18 +08:00
parent 56e3cc9bf4
commit 001416e399
8 changed files with 852 additions and 340 deletions

View File

@ -10,11 +10,32 @@ from typing import List, Dict, Optional
@dataclass
class Process:
"""进程数据结构"""
"""进程数据结构
新增 IO 模拟字段:
cpu_bursts: CPU 计算时间段列表 (交替: CPU->IO->CPU->IO...)
io_bursts: IO 操作时间段列表
io_wait: 进程在 IO 设备上等待的时间 (阻塞时间)
示例:
cpu_bursts = [5, 3, 2] # 3段CPU计算时间
io_bursts = [2, 1] # 2次IO操作
进程执行顺序: CPU(5) -> IO(2) -> CPU(3) -> IO(1) -> CPU(2)
"""
pid: str
arrival_time: int = 0
burst_time: int = 0
burst_time: int = 0 # 总CPU时间 = sum(cpu_bursts)
priority: int = 0 # 数值越小优先级越高
# ========== 新增 IO 模拟字段 ==========
cpu_bursts: List[int] = field(default_factory=list) # CPU计算时间段
io_bursts: List[int] = field(default_factory=list) # IO操作时间段
io_wait: int = 0 # IO设备等待时间
is_io_bound: bool = False # 是否为IO密集型进程
starts_with_io: bool = False # 是否以IO开始默认False=先CPU
# =====================================
# 调度相关状态
remaining_time: int = field(default=0)
start_time: int = -1
completion_time: int = 0
@ -22,9 +43,28 @@ class Process:
turnaround_time: int = 0
weighted_turnaround_time: float = 0.0 # 带权周转时间 = 周转时间/服务时间
response_time: int = 0
io_blocked_time: int = 0 # 因等待IO而阻塞的时间
def __post_init__(self):
self.remaining_time = self.burst_time
# 如果没有指定 cpu_bursts使用 burst_time 作为单段CPU时间
if not self.cpu_bursts and self.burst_time > 0:
self.cpu_bursts = [self.burst_time]
@property
def total_cpu_time(self) -> int:
"""总CPU计算时间"""
return sum(self.cpu_bursts) if self.cpu_bursts else self.burst_time
@property
def total_io_time(self) -> int:
"""总IO操作时间"""
return sum(self.io_bursts) if self.io_bursts else 0
@property
def num_io_operations(self) -> int:
"""IO操作次数"""
return len(self.io_bursts)
def reset(self):
"""重置进程状态"""
@ -35,18 +75,92 @@ class Process:
self.turnaround_time = 0
self.weighted_turnaround_time = 0.0
self.response_time = 0
self.io_blocked_time = 0
class ProcessScheduler:
"""进程调度器基类"""
"""进程调度器基类 (支持IO模拟)"""
# 进程状态
STATUS_NEW = 'NEW'
STATUS_READY = 'READY'
STATUS_RUNNING = 'RUNNING'
STATUS_IO_WAIT = 'IO_WAIT' # 等待IO完成
STATUS_TERMINATED = 'TERMINATED'
def __init__(self, processes: List[Process]):
self.processes = [p for p in processes]
self.results: List[Process] = []
self.gantt_chart: List[tuple] = [] # 甘特图记录 (时间, PID, 事件)
# IO 模拟相关
self.io_queue: List[Process] = [] # IO 等待队列 (等待IO完成的进程)
self.io_completion_events: List[tuple] = [] # IO 完成事件 (时间, 进程)
def init_process(self, p: Process, current_time: int):
"""初始化进程状态"""
p.status = self.STATUS_READY
p.current_cpu_idx = 0 # 当前执行的 cpu_burst 索引
p.current_io_idx = -1 # 当前等待的 io_burst 索引 (-1表示未进入IO)
p.remaining_cpu_time = sum(p.cpu_bursts) if p.cpu_bursts else p.burst_time
p.io_wait_time = 0 # 累计IO等待时间
if p.start_time == -1:
p.start_time = current_time
def execute_cpu(self, p: Process, time_slice: int, current_time: int):
"""执行一段 CPU burst"""
if p.current_cpu_idx >= len(p.cpu_bursts):
return 0 # 没有更多CPU burst
cpu_burst = p.cpu_bursts[p.current_cpu_idx]
execute_time = min(time_slice, cpu_burst)
p.remaining_cpu_time -= execute_time
# 记录甘特图
self.gantt_chart.append((current_time, p.pid, 'CPU', execute_time))
if execute_time >= cpu_burst:
# CPU burst 执行完毕
p.current_cpu_idx += 1
# 检查是否有对应的 IO burst
if p.current_cpu_idx - 1 < len(p.io_bursts):
# 进入 IO 等待
io_time = p.io_bursts[p.current_cpu_idx - 1]
p.current_io_idx = p.current_cpu_idx - 1
p.io_burst_remaining = io_time
p.status = self.STATUS_IO_WAIT
self.io_completion_events.append((current_time + io_time, p))
return execute_time
# 没有更多 burst进程结束
p.status = self.STATUS_TERMINATED
p.completion_time = current_time + execute_time
self.results.append(p)
return execute_time
else:
# 时间片用完但 CPU burst 还没完
return execute_time
def handle_io_completions(self, current_time: int):
"""处理当前时刻完成的 IO 事件"""
completed = []
for i, (io_time, p) in enumerate(self.io_completion_events):
if io_time <= current_time:
completed.append(i)
p.status = self.STATUS_READY
p.io_wait_time += io_time - (current_time - p.io_burst_remaining)
# 移除已处理的事件 (倒序删除避免索引问题)
for i in reversed(completed):
self.io_completion_events.pop(i)
return completed
def calculate_metrics(self, p: Process, current_time: int):
"""
计算进程性能指标
计算进程性能指标 (支持IO模拟)
周转时间 (Turnaround Time): CT - AT
进程从提交到完成的总时间
@ -57,57 +171,98 @@ class ProcessScheduler:
等待时间 (Waiting Time): TAT - BT
进程在就绪队列中等待的时间总和
注意: 这里只计算CPU等待时间不包括IO等待时间
响应时间 (Response Time): ST - AT
从提交到首次运行的时间
"""
p.completion_time = current_time
if p.status == self.STATUS_TERMINATED:
p.completion_time = current_time if p.completion_time == 0 else p.completion_time
else:
p.completion_time = current_time
p.turnaround_time = p.completion_time - p.arrival_time
p.waiting_time = p.turnaround_time - p.burst_time
p.response_time = p.start_time - p.arrival_time
# 等待时间 = 周转时间 - 总CPU时间 - IO等待时间
p.waiting_time = p.turnaround_time - p.total_cpu_time - p.io_wait_time
if p.waiting_time < 0:
p.waiting_time = 0
p.response_time = p.start_time - p.arrival_time if p.start_time > 0 else 0
# 带权周转时间 = 周转时间 / 服务时间
p.weighted_turnaround_time = p.turnaround_time / p.burst_time if p.burst_time > 0 else 0
p.io_wait = p.io_wait_time
def print_results(self, algorithm_name: str) -> Dict:
"""打印调度结果"""
"""打印调度结果 (支持IO模拟)"""
n = len(self.results)
if n == 0:
return {}
avg_waiting = sum(p.waiting_time for p in self.results) / n
avg_turnaround = sum(p.turnaround_time for p in self.results) / n
avg_weighted_turnaround = sum(p.weighted_turnaround_time for p in self.results) / n
avg_response = sum(p.response_time for p in self.results) / n
print(f"\n{'='*70}")
# 计算IO相关指标
total_io_time = sum(p.total_io_time for p in self.results)
total_io_wait = sum(p.io_wait for p in self.results)
avg_io_wait = total_io_wait / n if n > 0 else 0
io_bound_count = sum(1 for p in self.results if p.is_io_bound)
print(f"\n{'='*85}")
print(f"算法: {algorithm_name}")
print(f"{'='*70}")
print(f"{'PID':<6}{'到达':<6}{'服务':<6}{'开始':<6}{'完成':<6}"
f"{'等待':<6}{'周转':<6}{'带权周转':<10}{'响应':<6}")
print("-" * 70)
print(f"{'='*85}")
print(f"{'PID':<6}{'类型':<6}{'起始':<6}{'到达':<6}{'服务':<6}{'IO次数':<6}{'IO时间':<8}"
f"{'周转':<6}{'CPU等待':<8}{'IO等待':<8}{'响应':<6}")
print("-" * 85)
for p in self.results:
print(f"{p.pid:<6}{p.arrival_time:<6}{p.burst_time:<6}"
f"{p.start_time:<6}{p.completion_time:<6}"
f"{p.waiting_time:<6}{p.turnaround_time:<6}"
f"{p.weighted_turnaround_time:<10.2f}"
f"{p.response_time:<6}")
proc_type = "IO" if p.is_io_bound else "CPU"
start_phase = "IO" if p.starts_with_io else "CPU"
print(f"{p.pid:<6}{proc_type:<6}{start_phase:<6}{p.arrival_time:<6}{p.burst_time:<6}"
f"{p.num_io_operations:<6}{p.total_io_time:<8}"
f"{p.turnaround_time:<6}{p.waiting_time:<8}{p.io_wait:<8}{p.response_time:<6}")
print("-" * 70)
print(f"{'平均等待时间:':<18} {avg_waiting:.2f}")
print(f"{'平均周转时间:':<18} {avg_turnaround:.2f}")
print(f"{'平均带权周转时间:':<18} {avg_weighted_turnaround:.2f}")
print(f"{'平均响应时间:':<18} {avg_response:.2f}")
print("-" * 85)
print(f"{'平均等待时间:':<22} {avg_waiting:.2f}")
print(f"{'平均周转时间:':<22} {avg_turnaround:.2f}")
print(f"{'平均带权周转时间:':<22} {avg_weighted_turnaround:.2f}")
print(f"{'平均响应时间:':<22} {avg_response:.2f}")
# CPU 利用率
total_burst = sum(p.burst_time for p in self.results)
# CPU 利用率计算 (考虑IO模拟)
total_cpu_time = sum(p.total_cpu_time for p in self.results) # 纯CPU时间
total_time = self.results[-1].completion_time - self.results[0].arrival_time
utilization = (total_burst / total_time) * 100 if total_time > 0 else 0
print(f"{'CPU 利用率:':<18} {utilization:.2f}%")
# CPU利用率 = CPU执行时间 / 总时间
# 注意: IO期间CPU可以运行其他进程所以利用率应该更高
utilization = (total_cpu_time / total_time) * 100 if total_time > 0 else 0
# 计算CPU实际空闲时间
cpu_busy_time = len(self.gantt_chart) * 1 # 每个时间单位被计入
# 简化: 空闲时间 = 总时间 - CPU总执行时间
idle_time = total_time - total_cpu_time
print(f"\n{'='*85}")
print("性能统计")
print("-" * 85)
print(f"{'总执行时间:':<22} {total_time}")
print(f"{'总CPU时间:':<22} {total_cpu_time}")
print(f"{'CPU利用率:':<22} {utilization:.2f}%")
print(f"{'总IO时间:':<22} {total_io_time}")
print(f"{'总IO等待时间:':<22} {total_io_wait}")
print(f"{'平均IO等待:':<22} {avg_io_wait:.2f}")
print(f"{'IO密集型进程:':<22} {io_bound_count}/{n}")
return {
'avg_waiting': avg_waiting,
'avg_turnaround': avg_turnaround,
'avg_weighted_turnaround': avg_weighted_turnaround,
'avg_response': avg_response,
'cpu_utilization': utilization
'cpu_utilization': utilization,
'total_time': total_time,
'total_cpu_time': total_cpu_time,
'total_io_time': total_io_time,
'total_io_wait': total_io_wait,
'avg_io_wait': avg_io_wait,
'io_bound_count': io_bound_count
}
@ -116,10 +271,14 @@ def generate_random_processes(
seed: Optional[int] = 42,
arrival_range: tuple = (0, 50),
burst_range: tuple = (1, 20),
priority_range: tuple = (1, 10)
priority_range: tuple = (1, 10),
io_probability: float = 0.5, # 进程有IO操作的概率
io_count_range: tuple = (1, 4), # IO操作次数范围
io_time_range: tuple = (3, 15), # 每次IO时间范围
io_first_prob: float = 0.0, # 以IO开始的概率 (0.0=全部先CPU, 1.0=全部先IO)
) -> List[Process]:
"""
随机生成测试进程集
随机生成测试进程集 (支持IO模拟)
Args:
n: 进程数量
@ -127,20 +286,95 @@ def generate_random_processes(
arrival_range: 到达时间范围 (min, max)
burst_range: 服务时间范围 (min, max)
priority_range: 优先级范围 (min, max)
io_probability: 进程有IO操作的概率 (0.0-1.0)
io_count_range: IO操作次数范围 (min, max)
io_time_range: 每次IO时间范围 (min, max)
io_first_prob: 以IO开始的概率 (0.0=全部先CPU, 1.0=全部先IO, 0.5=随机)
Returns:
进程列表
示例:
# 生成10个进程50%有IO全部先CPU
processes = generate_random_processes(n=10, io_probability=0.5)
# 生成IO密集型场景30%以IO开始
processes = generate_random_processes(n=10, io_probability=0.8, io_first_prob=0.3)
"""
if seed is not None:
random.seed(seed)
processes = []
for i in range(n):
# 生成基本属性
arrival = random.randint(*arrival_range)
total_burst = random.randint(*burst_range)
priority = random.randint(*priority_range)
# 确定是否为IO密集型进程
is_io_bound = random.random() < io_probability
# 确定起始阶段
starts_with_io = random.random() < io_first_prob if io_first_prob > 0 else False
cpu_bursts = []
io_bursts = []
if is_io_bound:
# IO密集型: 短CPU计算 + 长IO等待
num_io = random.randint(*io_count_range)
if starts_with_io:
# 先IO再CPU: IO -> CPU -> IO -> CPU -> ...
for j in range(num_io):
# IO burst
io_time = random.randint(*io_time_range)
io_bursts.append(io_time)
# CPU burst
remaining = total_burst - sum(cpu_bursts)
max_cpu = min(3, remaining - (num_io - j - 1))
if max_cpu < 1:
max_cpu = 1
cpu_time = random.randint(1, max_cpu)
cpu_bursts.append(cpu_time)
# 最后一段CPU
remaining = total_burst - sum(cpu_bursts)
if remaining > 0:
cpu_bursts.append(remaining)
else:
# 先CPU再IO: CPU -> IO -> CPU -> IO -> ...
remaining = total_burst
for j in range(num_io + 1):
if j < num_io:
# CPU burst: 短时间 (1-3)
max_cpu = min(3, remaining - (num_io - j))
if max_cpu < 1:
max_cpu = 1
cpu_time = random.randint(1, max_cpu)
else:
# 最后一段CPU时间
cpu_time = remaining
if cpu_time > 0:
cpu_bursts.append(cpu_time)
remaining -= cpu_time
if j < num_io and remaining > 0:
# IO burst: 较长时间 (长IO等待)
io_time = random.randint(*io_time_range)
io_bursts.append(io_time)
else:
# CPU密集型: 长CPU计算 + 无/少IO
cpu_bursts = [total_burst]
p = Process(
pid=f'P{i+1}',
arrival_time=random.randint(*arrival_range),
burst_time=random.randint(*burst_range),
priority=random.randint(*priority_range)
arrival_time=arrival,
burst_time=total_burst,
priority=priority,
cpu_bursts=cpu_bursts,
io_bursts=io_bursts,
is_io_bound=is_io_bound,
starts_with_io=starts_with_io
)
processes.append(p)
@ -150,24 +384,64 @@ def generate_random_processes(
def print_processes(processes: List[Process], title: str = "测试数据"):
"""打印进程信息"""
print(f"\n{'='*60}")
"""打印进程信息 (包含IO模拟信息)"""
print(f"\n{'='*80}")
print(f"{title}")
print(f"{'='*60}")
print(f"{'PID':<8}{'到达时间':<10}{'服务时间':<10}{'优先级':<10}")
print("-" * 60)
print(f"{'='*80}")
print(f"{'PID':<6}{'类型':<6}{'起始':<6}{'到达':<6}{'服务':<6}{'IO次数':<6}{'IO时间':<8}{'优先级':<6}")
print("-" * 80)
io_bound_count = 0
io_first_count = 0
for p in processes:
print(f"{p.pid:<8}{p.arrival_time:<10}{p.burst_time:<10}{p.priority:<10}")
proc_type = "IO" if p.is_io_bound else "CPU"
start_phase = "IO" if p.starts_with_io else "CPU"
if p.is_io_bound:
io_bound_count += 1
if p.starts_with_io:
io_first_count += 1
io_time = p.total_io_time
print(f"{p.pid:<6}{proc_type:<6}{start_phase:<6}{p.arrival_time:<6}{p.burst_time:<6}"
f"{p.num_io_operations:<6}{io_time:<8}{p.priority:<6}")
print("-" * 80)
print(f"总进程数: {len(processes)}, CPU密集型: {len(processes)-io_bound_count}, IO密集型: {io_bound_count}")
print(f"起始阶段: 先CPU: {len(processes)-io_first_count}, 先IO: {io_first_count}")
# 详细显示有IO的进程的CPU和IO burst
io_processes = [p for p in processes if p.io_bursts]
if io_processes:
print(f"\n{'='*80}")
print("IO 操作详细 (执行模式)")
print("-" * 80)
for p in io_processes:
# 构建执行模式字符串
pattern = []
if p.starts_with_io:
# 先IO再CPU
for i, io in enumerate(p.io_bursts):
pattern.append(f"IO({io})")
if i < len(p.cpu_bursts):
pattern.append(f"CPU({p.cpu_bursts[i]})")
else:
# 先CPU再IO
for i, cpu in enumerate(p.cpu_bursts):
pattern.append(f"CPU({cpu})")
if i < len(p.io_bursts):
pattern.append(f"IO({p.io_bursts[i]})")
print(f"{p.pid}: {' -> '.join(pattern)}")
def print_comparison(results: Dict[str, Dict]):
"""打印算法比较结果"""
print("\n" + "="*90)
"""打印算法比较结果 (包含IO指标)"""
print("\n" + "="*100)
print("算法性能比较")
print("="*90)
print(f"{'算法':<10}{'平均等待':<12}{'平均周转':<12}{'平均带权周转':<14}{'平均响应':<12}{'CPU利用率':<12}")
print("-" * 90)
print("="*100)
print(f"{'算法':<8}{'平均等待':<10}{'平均周转':<10}{'平均带权周转':<12}{'平均响应':<10}{'CPU利用率':<10}{'IO阻塞':<10}")
print("-" * 100)
for name, metrics in results.items():
print(f"{name:<10}{metrics['avg_waiting']:<12.2f}{metrics['avg_turnaround']:<12.2f}"
f"{metrics.get('avg_weighted_turnaround', 0):<14.2f}"
f"{metrics['avg_response']:<12.2f}{metrics['cpu_utilization']:<12.2f}%")
print(f"{name:<8}{metrics['avg_waiting']:<10.2f}{metrics['avg_turnaround']:<10.2f}"
f"{metrics.get('avg_weighted_turnaround', 0):<12.2f}"
f"{metrics['avg_response']:<10.2f}"
f"{metrics['cpu_utilization']:<10.2f}%"
f"{metrics.get('avg_io_wait', 0):<10.2f}")

View File

@ -2,9 +2,12 @@
"""
先来先服务调度算法 (FCFS)
First Come First Served
支持 IO 模拟
"""
from typing import List, Dict
from typing import List, Dict, Tuple
from collections import deque
import heapq
from base import (
Process,
@ -15,28 +18,97 @@ from base import (
class FCFSScheduler(ProcessScheduler):
"""先来先服务调度 (First Come First Served)"""
"""先来先服务调度 (First Come First Served)
支持 IO 模拟:
- 进程执行一个 CPU burst 后进入 IO 等待
- IO 等待期间 CPU 可以调度其他就绪进程
- IO 完成时进程回到就绪队列
"""
def schedule(self) -> Dict:
"""FCFS 调度算法"""
# 按到达时间排序
ready_queue = sorted(self.processes, key=lambda p: (p.arrival_time, p.pid))
"""FCFS 调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
# 事件队列: (时间, 事件类型, 唯一ID, 进程)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
ready_queue = deque() # 就绪队列 (按到达顺序)
completed = []
current_time = 0
for p in ready_queue:
if p.arrival_time > current_time:
current_time = p.arrival_time
last_processed_time = 0
p.start_time = current_time
current_time += p.burst_time
self.calculate_metrics(p, current_time)
self.results.append(p)
while len(completed) < len(all_processes):
# 1. 处理所有当前时刻的事件
while events and events[0][0] <= current_time:
event_time, event_type, uid, p = heapq.heappop(events)
if event_type == 'arrival':
p.status = self.STATUS_READY
ready_queue.append(p)
elif event_type == 'io_complete':
if p.status == self.STATUS_IO_WAIT:
p.status = self.STATUS_READY
ready_queue.append(p)
# 2. 如果就绪队列为空,推进时间到下一个事件
if not ready_queue:
if events:
current_time = events[0][0]
continue
else:
break
# 3. FCFS: 选择队首进程
current_process = ready_queue.popleft()
if current_process.start_time == -1:
current_process.start_time = current_time
current_process.status = self.STATUS_RUNNING
# 4. 执行 CPU burst
if current_process.current_cpu_idx < len(current_process.cpu_bursts):
cpu_burst = current_process.cpu_bursts[current_process.current_cpu_idx]
self.gantt_chart.append((current_time, current_process.pid, 'CPU', cpu_burst))
current_time += cpu_burst
current_process.remaining_cpu_time -= cpu_burst
current_process.current_cpu_idx += 1
# 5. 检查是否有 IO burst
io_idx = current_process.current_cpu_idx - 1
if io_idx < len(current_process.io_bursts):
# 进入 IO 等待,添加 IO 完成事件
io_time = current_process.io_bursts[io_idx]
current_process.status = self.STATUS_IO_WAIT
io_complete_time = current_time + io_time
heapq.heappush(events, (io_complete_time, 'io_complete', id(current_process), current_process))
else:
# 进程完成
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
else:
# 进程完成
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
self.results = completed
return self.print_results("FCFS (先来先服务)")
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5, io_first_prob=0.3)
print_processes(processes, "测试数据")
scheduler = FCFSScheduler(processes)

View File

@ -1,10 +1,11 @@
#!/usr/bin/env python3
"""
高响应比优先调度算法 (HRRN)
Highest Response Ratio Next
支持 IO 模拟
"""
from typing import List, Dict
import heapq
from base import (
Process,
@ -15,57 +16,95 @@ from base import (
class HRRNScheduler(ProcessScheduler):
"""
高响应比优先调度 (Highest Response Ratio Next)
"""高响应比优先调度
响应比 = (等待时间 + 服务时间) / 服务时间
= 1 + 等待时间 / 服务时间
特点
- 非抢占式
- 综合考虑了等待时间和服务时间
- 避免长作业饥饿问题
支持 IO 模拟
"""
def calculate_response_ratio(self, p: Process, current_time: int) -> float:
"""计算响应比"""
waiting_time = current_time - p.arrival_time
return 1 + (waiting_time / p.burst_time) if p.burst_time > 0 else float('inf')
def schedule(self) -> Dict:
"""HRRN 调度算法"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
ready_queue: List[Process] = []
"""HRRN 调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
ready_queue = [] # (response_ratio, pid, process)
completed = []
current_time = 0
completed = 0
while completed < len(processes):
# 添加所有到达的进程
for p in processes:
if p.arrival_time <= current_time and p not in ready_queue and p not in self.results:
while len(completed) < len(all_processes):
while events and events[0][0] <= current_time:
event_time, event_type, uid, p = heapq.heappop(events)
if event_type == 'arrival':
p.status = self.STATUS_READY
ready_queue.append(p)
elif event_type == 'io_complete':
if p.status == self.STATUS_IO_WAIT:
p.status = self.STATUS_READY
ready_queue.append(p)
if ready_queue:
# 计算每个进程的响应比,选择最高的
ready_queue.sort(
key=lambda p: self.calculate_response_ratio(p, current_time),
reverse=True # 响应比高优先
)
p = ready_queue.pop(0)
if not ready_queue:
if events:
current_time = events[0][0]
continue
else:
break
p.start_time = current_time
current_time += p.burst_time
self.calculate_metrics(p, current_time)
self.results.append(p)
completed += 1
# 计算响应比
for p in ready_queue:
wait_time = current_time - p.arrival_time
remaining = p.remaining_cpu_time if p.remaining_cpu_time > 0 else p.total_cpu_time
if remaining > 0:
p.response_ratio = (wait_time + remaining) / remaining
else:
p.response_ratio = float('inf')
ready_queue.sort(key=lambda x: (-x.response_ratio, id(x)))
current_process = ready_queue.pop(0)
if current_process.start_time == -1:
current_process.start_time = current_time
current_process.status = self.STATUS_RUNNING
if current_process.current_cpu_idx < len(current_process.cpu_bursts):
cpu_burst = current_process.cpu_bursts[current_process.current_cpu_idx]
self.gantt_chart.append((current_time, current_process.pid, 'CPU', cpu_burst))
current_time += cpu_burst
current_process.remaining_cpu_time -= cpu_burst
current_process.current_cpu_idx += 1
io_idx = current_process.current_cpu_idx - 1
if io_idx < len(current_process.io_bursts):
io_time = current_process.io_bursts[io_idx]
current_process.status = self.STATUS_IO_WAIT
heapq.heappush(events, (current_time + io_time, 'io_complete', id(current_process), current_process))
else:
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
else:
current_time += 1
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
self.results = completed
return self.print_results("HRRN (高响应比优先)")
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5)
print_processes(processes, "测试数据")
scheduler = HRRNScheduler(processes)

View File

@ -32,13 +32,21 @@ from mlfq import MLFQScheduler
from hrrn import HRRNScheduler
# 预设演示数据
# 预设演示数据 (包含IO模拟)
DEMO_PROCESSES = [
Process(pid='P1', arrival_time=0, burst_time=7, priority=3),
Process(pid='P2', arrival_time=2, burst_time=4, priority=1),
Process(pid='P3', arrival_time=4, burst_time=1, priority=4),
Process(pid='P4', arrival_time=5, burst_time=4, priority=2),
Process(pid='P5', arrival_time=6, burst_time=2, priority=3),
# CPU密集型进程
Process(pid='P1', arrival_time=0, burst_time=7, priority=3,
cpu_bursts=[7], io_bursts=[], is_io_bound=False),
# IO密集型进程: CPU -> IO -> CPU -> IO -> CPU
Process(pid='P2', arrival_time=2, burst_time=10, priority=1,
cpu_bursts=[3, 2, 3], io_bursts=[5, 4], is_io_bound=True),
Process(pid='P3', arrival_time=4, burst_time=1, priority=4,
cpu_bursts=[1], io_bursts=[], is_io_bound=False),
# IO密集型进程
Process(pid='P4', arrival_time=5, burst_time=8, priority=2,
cpu_bursts=[2, 2, 2], io_bursts=[6, 5], is_io_bound=True),
Process(pid='P5', arrival_time=6, burst_time=2, priority=3,
cpu_bursts=[2], io_bursts=[], is_io_bound=False),
]
@ -127,6 +135,14 @@ def main():
help='服务时间范围 (格式: min,max)')
parser.add_argument('--priority', type=str, default='1,10',
help='优先级范围 (格式: min,max)')
parser.add_argument('--io-prob', type=float, default=0.5,
help='进程有IO操作的概率 0.0-1.0 (默认: 0.5)')
parser.add_argument('--io-count', type=str, default='1,4',
help='IO操作次数范围 (格式: min,max, 默认: 1,4)')
parser.add_argument('--io-time', type=str, default='3,15',
help='每次IO时间范围 (格式: min,max, 默认: 3,15)')
parser.add_argument('--io-first', type=float, default=0.0,
help='以IO开始的概率 0.0-1.0 (默认: 0.0, 即全部先CPU)')
args = parser.parse_args()
@ -144,6 +160,8 @@ def main():
arrival_range = tuple(map(int, args.arrival.split(',')))
burst_range = tuple(map(int, args.burst.split(',')))
priority_range = tuple(map(int, args.priority.split(',')))
io_count_range = tuple(map(int, args.io_count.split(',')))
io_time_range = tuple(map(int, args.io_time.split(',')))
seed = args.seed if args.seed != -1 else None
@ -152,7 +170,11 @@ def main():
seed=seed,
arrival_range=arrival_range,
burst_range=burst_range,
priority_range=priority_range
priority_range=priority_range,
io_probability=args.io_prob,
io_count_range=io_count_range,
io_time_range=io_time_range,
io_first_prob=args.io_first
)
title = f"随机测试数据 (n={args.num}, seed={args.seed if seed else 'None'})"

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python3
"""
多级反馈队列调度算法 (MLFQ)
Multilevel Feedback Queue
支持 IO 模拟
"""
from collections import deque
from typing import List, Dict
from collections import deque
import heapq
from base import (
Process,
@ -16,83 +17,127 @@ from base import (
class MLFQScheduler(ProcessScheduler):
"""多级反馈队列调度 (Multilevel Feedback Queue)"""
"""多级反馈队列调度"""
def __init__(self, processes: List[Process], queues: List[int] = None):
def __init__(self, processes: List[Process], num_queues: int = 3, base_time_slice: int = 4):
super().__init__(processes)
# 每层队列的时间片大小
self.queues = queues or [4, 8, 16]
self.aging_time = 50
self.num_queues = num_queues
self.base_time_slice = base_time_slice
def get_time_slice(self, queue_idx: int) -> int:
return self.base_time_slice * (2 ** queue_idx)
def schedule(self) -> Dict:
"""MLFQ 调度算法"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
"""MLFQ 调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
n = len(all_processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
p.queue_idx = 0
# 事件: (时间, 类型, uid, 进程)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
queues = [deque() for _ in range(self.num_queues)]
completed = []
io_waiting = {} # {进程: IO完成时间}
queues = [deque() for _ in self.queues]
current_time = 0
completed = 0
index = 0
max_iterations = 10000 # 防止死循环
iterations = 0
while completed < len(processes):
while index < len(processes) and processes[index].arrival_time <= current_time:
queues[0].append(processes[index])
index += 1
while len(completed) < n and iterations < max_iterations:
iterations += 1
# 老化
for i in range(1, len(queues)):
for p in list(queues[i]):
wait_time = current_time - p.arrival_time - (p.burst_time - p.remaining_time)
if wait_time > self.aging_time:
queues[i].remove(p)
queues[max(0, i-1)].append(p)
# 1. 处理到达事件
while events and events[0][0] <= current_time:
_, etype, _, p = heapq.heappop(events)
if etype == 'arrival':
p.status = self.STATUS_READY
queues[0].append(p)
elif etype == 'io_complete':
io_waiting.pop(p.pid, None)
p.status = self.STATUS_READY
queues[p.queue_idx].append(p)
queue_idx = -1
for i in range(len(queues)):
# 2. 检查 IO 完成
completed_io = []
for p, io_end_time in io_waiting.items():
if io_end_time <= current_time:
completed_io.append(p)
for p in completed_io:
io_waiting.pop(p.pid, None)
p.status = self.STATUS_READY
queues[p.queue_idx].append(p)
# 3. 找最高优先级非空队列
q_idx = -1
for i in range(self.num_queues):
if queues[i]:
queue_idx = i
q_idx = i
break
if queue_idx >= 0:
p = queues[queue_idx].popleft()
if q_idx == -1:
# 所有队列为空,推进时间
next_events = [e[0] for e in events if e[0] > current_time]
next_io = [t for t in io_waiting.values() if t > current_time]
next_times = next_events + next_io
if next_times:
current_time = min(next_times)
continue
if p.start_time == -1:
p.start_time = current_time
# 4. 取进程执行
p = queues[q_idx].popleft()
exec_time = min(self.queues[queue_idx], p.remaining_time)
p.remaining_time -= exec_time
current_time += exec_time
if p.start_time == -1:
p.start_time = current_time
p.status = self.STATUS_RUNNING
while index < len(processes) and processes[index].arrival_time <= current_time:
queues[0].append(processes[index])
index += 1
ts = self.get_time_slice(q_idx)
if p.remaining_time > 0:
if queue_idx < len(queues) - 1:
queues[queue_idx + 1].append(p)
if p.current_cpu_idx < len(p.cpu_bursts):
cpu_burst = p.cpu_bursts[p.current_cpu_idx]
exec_t = min(ts, cpu_burst)
self.gantt_chart.append((current_time, p.pid, 'CPU', exec_t))
current_time += exec_t
p.remaining_cpu_time -= exec_t
if exec_t >= cpu_burst:
p.current_cpu_idx += 1
io_idx = p.current_cpu_idx - 1
if io_idx < len(p.io_bursts):
io_t = p.io_bursts[io_idx]
p.status = self.STATUS_IO_WAIT
io_waiting[p.pid] = current_time + io_t
heapq.heappush(events, (current_time + io_t, 'io_complete', id(p), p))
else:
queues[queue_idx].append(p)
p.status = self.STATUS_TERMINATED
p.completion_time = current_time
self.calculate_metrics(p, current_time)
completed.append(p)
else:
self.calculate_metrics(p, current_time)
self.results.append(p)
completed += 1
p.status = self.STATUS_READY
nq = min(q_idx + 1, self.num_queues - 1)
p.queue_idx = nq
queues[nq].append(p)
else:
current_time += 1
p.status = self.STATUS_TERMINATED
p.completion_time = current_time
self.calculate_metrics(p, current_time)
completed.append(p)
return self.print_results(f"MLFQ (多级反馈队列, 队列时间片={self.queues})")
self.results = completed
return self.print_results("MLFQ (多级反馈队列)")
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5)
print_processes(processes, "测试数据")
print("\n" + "="*60)
print("多级反馈队列调度 (默认配置)")
print("="*60)
scheduler1 = MLFQScheduler(processes)
scheduler1.schedule()
print("\n" + "="*60)
print("多级反馈队列调度 (自定义配置 [2, 5, 10])")
print("="*60)
scheduler2 = MLFQScheduler(processes, queues=[2, 5, 10])
scheduler2.schedule()
scheduler = MLFQScheduler(processes)
scheduler.schedule()

View File

@ -1,9 +1,11 @@
#!/usr/bin/env python3
"""
优先级调度算法 (Priority Scheduling)
优先级调度算法 (Priority)
支持 IO 模拟
"""
from typing import List, Dict
import heapq
from base import (
Process,
@ -14,95 +16,88 @@ from base import (
class PriorityScheduler(ProcessScheduler):
"""优先级调度"""
"""优先级调度 (数值越小优先级越高)
支持 IO 模拟
"""
def __init__(self, processes: List[Process], preemptive: bool = False):
super().__init__(processes)
self.preemptive = preemptive
def schedule(self) -> Dict:
"""优先级调度算法"""
if self.preemptive:
return self.schedule_preemptive()
return self.schedule_non_preemptive()
"""优先级调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
ready_queue = [] # (priority, pid, process)
completed = []
def schedule_non_preemptive(self) -> Dict:
"""非抢占式优先级调度"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
ready_queue: List[Process] = []
current_time = 0
completed = 0
while completed < len(processes):
for p in processes:
if p.arrival_time <= current_time and p not in ready_queue and p not in self.results:
ready_queue.append(p)
while len(completed) < len(all_processes):
while events and events[0][0] <= current_time:
event_time, event_type, uid, p = heapq.heappop(events)
if ready_queue:
ready_queue.sort(key=lambda p: p.priority)
p = ready_queue.pop(0)
if event_type == 'arrival':
p.status = self.STATUS_READY
heapq.heappush(ready_queue, (p.priority, id(p), p))
elif event_type == 'io_complete':
if p.status == self.STATUS_IO_WAIT:
p.status = self.STATUS_READY
heapq.heappush(ready_queue, (p.priority, id(p), p))
p.start_time = current_time
current_time += p.burst_time
self.calculate_metrics(p, current_time)
self.results.append(p)
completed += 1
else:
current_time += 1
if not ready_queue:
if events:
current_time = events[0][0]
continue
else:
break
return self.print_results("优先级调度 (非抢占)")
_, _, current_process = heapq.heappop(ready_queue)
def schedule_preemptive(self) -> Dict:
"""抢占式优先级调度"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
ready_queue: List[Process] = []
current_time = 0
completed = 0
current_process = None
if current_process.start_time == -1:
current_process.start_time = current_time
while completed < len(processes):
for p in processes:
if p.arrival_time <= current_time and p not in ready_queue and p not in self.results:
ready_queue.append(p)
current_process.status = self.STATUS_RUNNING
if ready_queue:
ready_queue.sort(key=lambda p: p.priority)
if current_process.current_cpu_idx < len(current_process.cpu_bursts):
cpu_burst = current_process.cpu_bursts[current_process.current_cpu_idx]
if current_process is None or current_process.priority > ready_queue[0].priority:
if current_process and current_process.remaining_time > 0:
ready_queue.append(current_process)
self.gantt_chart.append((current_time, current_process.pid, 'CPU', cpu_burst))
current_process = ready_queue.pop(0)
current_time += cpu_burst
current_process.remaining_cpu_time -= cpu_burst
current_process.current_cpu_idx += 1
if current_process.start_time == -1:
current_process.start_time = current_time
current_process.remaining_time -= 1
current_time += 1
if current_process.remaining_time == 0:
io_idx = current_process.current_cpu_idx - 1
if io_idx < len(current_process.io_bursts):
io_time = current_process.io_bursts[io_idx]
current_process.status = self.STATUS_IO_WAIT
heapq.heappush(events, (current_time + io_time, 'io_complete', id(current_process), current_process))
else:
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
self.results.append(current_process)
completed += 1
current_process = None
completed.append(current_process)
else:
current_time += 1
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
return self.print_results("优先级调度 (抢占)")
self.results = completed
return self.print_results("Priority (优先级调度)")
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5)
print_processes(processes, "测试数据")
print("\n" + "="*60)
print("非抢占式优先级调度")
print("="*60)
scheduler1 = PriorityScheduler(processes, preemptive=False)
scheduler1.schedule()
print("\n" + "="*60)
print("抢占式优先级调度")
print("="*60)
scheduler2 = PriorityScheduler(processes, preemptive=True)
scheduler2.schedule()
scheduler = PriorityScheduler(processes)
scheduler.schedule()

View File

@ -1,11 +1,12 @@
#!/usr/bin/env python3
"""
时间片轮转调度算法 (RR)
Round Robin
支持 IO 模拟
"""
from collections import deque
from typing import List, Dict
from collections import deque
import heapq
from base import (
Process,
@ -16,58 +17,110 @@ from base import (
class RoundRobinScheduler(ProcessScheduler):
"""时间片轮转调度 (Round Robin)"""
"""时间片轮转调度"""
def __init__(self, processes: List[Process], time_slice: int = 4):
super().__init__(processes)
self.time_slice = time_slice
def schedule(self) -> Dict:
"""RR 调度算法"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
"""RR 调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
n = len(all_processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
ready_queue = deque()
completed = []
io_waiting = {} # {进程PID: IO完成时间}
current_time = 0
completed = 0
index = 0
max_iterations = 10000
iterations = 0
while completed < len(processes):
while index < len(processes) and processes[index].arrival_time <= current_time:
ready_queue.append(processes[index])
index += 1
while len(completed) < n and iterations < max_iterations:
iterations += 1
if ready_queue:
p = ready_queue.popleft()
if p.start_time == -1:
p.start_time = current_time
exec_time = min(self.time_slice, p.remaining_time)
p.remaining_time -= exec_time
current_time += exec_time
while index < len(processes) and processes[index].arrival_time <= current_time:
ready_queue.append(processes[index])
index += 1
if p.remaining_time > 0:
# 1. 处理到达事件
while events and events[0][0] <= current_time:
_, etype, _, p = heapq.heappop(events)
if etype == 'arrival':
p.status = self.STATUS_READY
ready_queue.append(p)
elif etype == 'io_complete':
io_waiting.pop(p.pid, None)
p.status = self.STATUS_READY
ready_queue.append(p)
else:
self.calculate_metrics(p, current_time)
self.results.append(p)
completed += 1
else:
current_time += 1
return self.print_results(f"RR (时间片轮转, time_slice={self.time_slice})")
# 2. 检查 IO 完成
completed_io = []
for p, io_end_time in io_waiting.items():
if io_end_time <= current_time:
completed_io.append(p)
for p in completed_io:
io_waiting.pop(p.pid, None)
p.status = self.STATUS_READY
ready_queue.append(p)
if not ready_queue:
# 队列为空,推进时间
next_events = [e[0] for e in events if e[0] > current_time]
next_io = [t for t in io_waiting.values() if t > current_time]
next_times = next_events + next_io
if next_times:
current_time = min(next_times)
continue
# 3. 取进程执行
p = ready_queue.popleft()
if p.start_time == -1:
p.start_time = current_time
p.status = self.STATUS_RUNNING
if p.current_cpu_idx < len(p.cpu_bursts):
cpu_burst = p.cpu_bursts[p.current_cpu_idx]
exec_t = min(self.time_slice, cpu_burst)
self.gantt_chart.append((current_time, p.pid, 'CPU', exec_t))
current_time += exec_t
p.remaining_cpu_time -= exec_t
if exec_t >= cpu_burst:
p.current_cpu_idx += 1
io_idx = p.current_cpu_idx - 1
if io_idx < len(p.io_bursts):
io_t = p.io_bursts[io_idx]
p.status = self.STATUS_IO_WAIT
io_waiting[p.pid] = current_time + io_t
heapq.heappush(events, (current_time + io_t, 'io_complete', id(p), p))
else:
p.status = self.STATUS_TERMINATED
p.completion_time = current_time
self.calculate_metrics(p, current_time)
completed.append(p)
else:
p.status = self.STATUS_READY
ready_queue.append(p)
else:
p.status = self.STATUS_TERMINATED
p.completion_time = current_time
self.calculate_metrics(p, current_time)
completed.append(p)
self.results = completed
return self.print_results(f"RR (时间片轮转, q={self.time_slice})")
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5)
print_processes(processes, "测试数据")
for ts in [2, 4, 8]:
print("\n" + "="*60)
print(f"时间片轮转 (time_slice={ts})")
print("="*60)
scheduler = RoundRobinScheduler(processes, time_slice=ts)
scheduler.schedule()
scheduler = RoundRobinScheduler(processes, time_slice=4)
scheduler.schedule()

View File

@ -1,10 +1,13 @@
#!/usr/bin/env python3
"""
短作业优先调度算法 (SJF)
Shortest Job First / Shortest Remaining Time First (SRTF)
最短作业优先调度算法 (SJF/SRTF)
Shortest Job First / Shortest Remaining Time First
支持 IO 模拟
"""
from typing import List, Dict
from collections import deque
import heapq
from base import (
Process,
@ -15,89 +18,98 @@ from base import (
class SJFScheduler(ProcessScheduler):
"""短作业优先调度 (Shortest Job First)"""
"""最短作业优先调度 (SJF/SRTF)
SJF: 非抢占式选择剩余时间最短的进程
SRTF: 抢占式选择剩余时间最短的进程
支持 IO 模拟
"""
def __init__(self, processes: List[Process], preemptive: bool = False):
super().__init__(processes)
self.preemptive = preemptive
def schedule(self) -> Dict:
"""SJF 调度算法"""
if self.preemptive:
return self.schedule_preemptive()
return self.schedule_non_preemptive()
"""SJF/SRTF 调度算法 (支持IO模拟)"""
all_processes = list(self.processes)
for p in all_processes:
self.init_process(p, p.arrival_time)
# 事件队列: (时间, 事件类型, 唯一ID, 进程)
events = []
for p in all_processes:
heapq.heappush(events, (p.arrival_time, 'arrival', id(p), p))
ready_queue = [] # 就绪队列 (需要排序)
completed = []
def schedule_non_preemptive(self) -> Dict:
"""非抢占式 SJF"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
ready_queue: List[Process] = []
current_time = 0
completed = 0
while completed < len(processes):
for p in processes:
if p.arrival_time <= current_time and p not in ready_queue and p not in self.results:
while len(completed) < len(all_processes):
# 处理事件
while events and events[0][0] <= current_time:
event_time, event_type, uid, p = heapq.heappop(events)
if event_type == 'arrival':
p.status = self.STATUS_READY
ready_queue.append(p)
elif event_type == 'io_complete':
if p.status == self.STATUS_IO_WAIT:
p.status = self.STATUS_READY
ready_queue.append(p)
if ready_queue:
ready_queue.sort(key=lambda p: p.burst_time)
p = ready_queue.pop(0)
if not ready_queue:
if events:
current_time = events[0][0]
continue
else:
break
p.start_time = current_time
current_time += p.burst_time
self.calculate_metrics(p, current_time)
self.results.append(p)
completed += 1
# 按剩余时间排序
ready_queue.sort(key=lambda p: (p.remaining_cpu_time, id(p)))
current_process = ready_queue.pop(0)
if current_process.start_time == -1:
current_process.start_time = current_time
current_process.status = self.STATUS_RUNNING
# 执行 CPU burst
if current_process.current_cpu_idx < len(current_process.cpu_bursts):
cpu_burst = current_process.cpu_bursts[current_process.current_cpu_idx]
self.gantt_chart.append((current_time, current_process.pid, 'CPU', cpu_burst))
current_time += cpu_burst
current_process.remaining_cpu_time -= cpu_burst
current_process.current_cpu_idx += 1
io_idx = current_process.current_cpu_idx - 1
if io_idx < len(current_process.io_bursts):
io_time = current_process.io_bursts[io_idx]
current_process.status = self.STATUS_IO_WAIT
heapq.heappush(events, (current_time + io_time, 'io_complete', id(current_process), current_process))
else:
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
else:
current_time += 1
current_process.status = self.STATUS_TERMINATED
current_process.completion_time = current_time
self.calculate_metrics(current_process, current_time)
completed.append(current_process)
return self.print_results("SJF (短作业优先 - 非抢占)")
def schedule_preemptive(self) -> Dict:
"""抢占式 SJF (SRTF)"""
processes = sorted(self.processes, key=lambda p: p.arrival_time)
ready_queue: List[Process] = []
current_time = 0
completed = 0
while completed < len(processes):
for p in processes:
if p.arrival_time <= current_time and p not in ready_queue and p not in self.results:
ready_queue.append(p)
if ready_queue:
ready_queue.sort(key=lambda p: p.remaining_time)
p = ready_queue[0]
if p.start_time == -1:
p.start_time = current_time
p.remaining_time -= 1
current_time += 1
if p.remaining_time == 0:
self.calculate_metrics(p, current_time)
self.results.append(p)
ready_queue.remove(p)
completed += 1
else:
current_time += 1
return self.print_results("SRTF (最短剩余时间优先 - 抢占)")
self.results = completed
algo_name = "SRTF (最短剩余时间优先)" if self.preemptive else "SJF (最短作业优先)"
return self.print_results(algo_name)
if __name__ == "__main__":
processes = generate_random_processes(n=5, seed=42)
processes = generate_random_processes(n=5, seed=42, io_probability=0.5)
print_processes(processes, "测试数据")
print("\n" + "="*60)
print("非抢占式 SJF")
print("="*60)
scheduler1 = SJFScheduler(processes, preemptive=False)
scheduler1.schedule()
print("\n" + "="*60)
print("抢占式 SJF (SRTF)")
print("="*60)
scheduler2 = SJFScheduler(processes, preemptive=True)
scheduler2.schedule()
print("\n--- SJF (非抢占) ---")
scheduler = SJFScheduler(processes, preemptive=False)
scheduler.schedule()