能否在Simpy中结合Preemptive Resource与Container实现优先级访问?
Simpy内存容器的优先级调度优化方案
你当前的memory类通过PreemptiveResource全局锁定容器,导致即使内存有剩余,其他进程也会被阻塞,不符合仅在资源不足时触发优先级调度的需求。以下是优化方案:
问题分析
当前方案用PreemptiveResource把容器的访问变成了互斥操作,不管剩余内存够不够,一次只能有一个进程访问容器。但实际需求是:内存充足时允许多进程同时获取,只有内存不足时,才让高优先级进程抢占低优先级进程的内存。
实现思路
- 移除全局的
PreemptiveResource,改为直接操作Container,同时增加对当前占用内存的进程的跟踪。 - 当进程请求内存时:
- 先检查容器剩余量是否满足需求,满足则直接分配并记录进程占用信息。
- 不满足时,按优先级从低到高抢占已分配的内存,释放低优先级进程的资源直到满足当前请求。
- 用Simpy的事件机制处理抢占逻辑,确保调度的正确性。
修改后的代码示例
import simpy from simpy import Environment, Container class Memory: def __init__(self, env: Environment, size: int, memory_name: str): self.env = env self.container = Container(env, size, size) self.memory_name = memory_name # 跟踪进程的内存占用:键为进程实例,值为(占用量, 优先级) self.process_usage = {} def request_memory(self, process, request_size: int, priority: int): """请求内存,仅在资源不足时触发优先级抢占""" # 先尝试直接获取 if self.container.level >= request_size: yield self.container.get(request_size) self.process_usage[process] = (request_size, priority) return # 内存不足,开始抢占低优先级进程的资源 # 按优先级升序排序当前占用进程(优先级低的先被抢占) sorted_processes = sorted( self.process_usage.items(), key=lambda x: x[1][1] ) needed = request_size - self.container.level for proc, (used_size, proc_priority) in sorted_processes: if proc_priority >= priority: # 优先级不低于当前进程,跳过 continue if needed <= 0: break # 计算可抢占的量:取进程占用量和剩余需要量的最小值 preempt_size = min(used_size, needed) # 释放内存 yield self.container.put(preempt_size) # 更新该进程的占用量 self.process_usage[proc] = (used_size - preempt_size, proc_priority) if self.process_usage[proc][0] == 0: del self.process_usage[proc] needed -= preempt_size # 现在内存足够,分配给当前进程 yield self.container.get(request_size) self.process_usage[process] = (request_size, priority) # 测试示例 def process(env, memory, name, request_size, priority): print(f"{env.now}: Process {name} (priority {priority}) requesting {request_size} memory") yield env.process(memory.request_memory(env.active_process, request_size, priority)) print(f"{env.now}: Process {name} acquired memory") # 模拟内存使用时间 yield env.timeout(5) # 释放内存 used_size, _ = memory.process_usage.pop(env.active_process) yield memory.container.put(used_size) print(f"{env.now}: Process {name} released memory") env = Environment() mem = Memory(env, 100, "MainMemory") # 启动低优先级进程先占用内存 env.process(process(env, mem, "P1", 60, 1)) env.process(process(env, mem, "P2", 30, 1)) # 稍后启动高优先级进程,需要50内存(此时剩余10,需要抢占) env.process(env.timeout(2) + process(env, mem, "P3", 50, 3)) env.run()
代码说明
process_usage字典跟踪每个进程的内存占用和优先级,方便后续抢占操作。request_memory方法先尝试直接分配内存,只有不足时才触发抢占逻辑。- 抢占时优先选择优先级最低的进程,逐步释放资源直到满足当前请求。
- 进程使用完内存后需要主动释放,并更新
process_usage记录。
内容的提问来源于stack exchange,提问作者miyoku
相关产品推荐
相关产品推荐

