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

SimPy如何实现替代AnyOf的互斥OneOf组件,仅允许单个进程触发

问题根因

当两个等待进程的超时时长完全相等时,两个timeout事件会被调度到SimPy同一时间点的普通优先级事件队列,AnyOf的触发回调要等当前时间点所有普通优先级事件执行完才会运行,此时两个进程都已经执行完毕,后续的中断逻辑自然不会生效。

解决方案1:自定义高优先级OneOf组件

你想要的高优先级OneOf可以直接继承SimPy的Condition类实现,核心逻辑是只要第一个事件触发,就立刻以最高优先级调度其余事件的中断操作,保证同时间点不会有第二个事件被处理:

import simpy
from simpy import Condition

class OneOf(Condition):
    def __init__(self, env, events):
        super().__init__(env, lambda evts: len(evts) >= 1, events)
        # 绑定回调,只要条件满足就立刻中断剩余事件
        self.callbacks.append(self._interrupt_remaining)
    
    def _interrupt_remaining(self, _):
        # 拿到第一个完成的事件后,直接用最高优先级调度中断
        for evt in self.events:
            if not evt.processed and hasattr(evt, 'interrupt'):
                # URGENT优先级为0,高于所有普通事件
                self.env.schedule(lambda: evt.interrupt(), priority=0)

# 测试代码和你原来的基本一致,只把AnyOf换成OneOf
def waitingprocess(env, waitingtime):
    try: 
        yield env.timeout(waitingtime)
    except:
        pass

def example(env):
    waitingtimeA = 1.0
    waitingtimeB = 1.0
    A = env.process(waitingprocess(env, waitingtimeA))
    B = env.process(waitingprocess(env, waitingtimeB))
    events = [A,B]
    yield OneOf(env, events)
    print('is A Processed:', A.processed)
    print('is B Processed:', B.processed)

env = simpy.Environment()
Example = env.process(example(env))
env.run()

运行后输出会随机只有一个进程为True,另一个为False,符合互斥触发的要求。

解决方案2:轻量改造现有逻辑,无需自定义组件

如果不想自定义组件,也可以给等待进程加一个全局互斥标记,只要有一个进程先执行到完成逻辑,就直接阻塞另一个的结果生效:

import simpy
from simpy import AnyOf

mutex = False

def waitingprocess(env, waitingtime):
    global mutex
    try: 
        yield env.timeout(waitingtime)
        # 加互斥判断,只有第一个到达的能生效
        if not mutex:
            mutex = True
        else:
            # 后续到达的直接抛中断模拟未处理
            raise simpy.Interrupt()
    except:
        pass

def example(env):
    global mutex
    mutex = False
    waitingtimeA = 1.0
    waitingtimeB = 1.0
    A = env.process(waitingprocess(env, waitingtimeA))
    B = env.process(waitingprocess(env, waitingtimeB))
    events = [A,B]
    yield AnyOf(env, events)
    for e in events:
        if not e.processed:
            e.interrupt()
    print('is A Processed:', A.processed)
    print('is B Processed:', B.processed)

env = simpy.Environment()
Example = env.process(example(env))
env.run()

内容的提问来源于stack exchange,提问作者Nick P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:45:04