You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Simpy中结合Preemptive Resource与Container实现优先级访问?

Simpy内存容器的优先级调度优化方案

你当前的memory类通过PreemptiveResource全局锁定容器,导致即使内存有剩余,其他进程也会被阻塞,不符合仅在资源不足时触发优先级调度的需求。以下是优化方案:

问题分析

当前方案用PreemptiveResource把容器的访问变成了互斥操作,不管剩余内存够不够,一次只能有一个进程访问容器。但实际需求是:内存充足时允许多进程同时获取,只有内存不足时,才让高优先级进程抢占低优先级进程的内存。

实现思路

  1. 移除全局的PreemptiveResource,改为直接操作Container,同时增加对当前占用内存的进程的跟踪。
  2. 当进程请求内存时:
    • 先检查容器剩余量是否满足需求,满足则直接分配并记录进程占用信息。
    • 不满足时,按优先级从低到高抢占已分配的内存,释放低优先级进程的资源直到满足当前请求。
  3. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:07:36