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

SimPy队列模拟中添加if语句后程序停滞的问题求助

问题分析与解决方案

你的问题核心在于SimPy进程的事件驱动机制被破坏:

原来的代码中,yield order_queue.get()是阻塞操作,会主动让出SimPy的事件循环,让其他进程(比如生成订单的进程)有机会运行。但添加if判断后,当条件不满足时,process_orders进程会进入无限忙循环——它一直在重复执行while True和if检查,却没有任何yield语句让出控制权,导致SimPy的事件循环被完全占用,其他进程根本得不到运行机会,自然就停止反馈了。

调试时无法进入if块,大概率是因为条件一直不满足,进程卡在循环里反复检查,没有触发任何事件切换。

正确的实现方式

SimPy的设计思路是基于事件触发,而非主动轮询。你需要用SimPy的同步原语或合理的事件等待逻辑,实现“满足特定条件时才处理订单”的需求,而非自己写轮询判断。

方案1:先获取订单,再等待到指定时间处理

如果订单的start_prep是已知的,服务进程可以先获取订单,若当前时间不满足条件,就等待到start_prep时间再执行服务流程:

def process_orders(env, order_queue):
    while True:
        order = yield order_queue.get()
        
        # 如果当前时间未到start_prep,先等待到该时间点
        if round(env.now, 5) < round(order.start_prep, 5):
            wait_time = order.start_prep - env.now
            yield env.timeout(wait_time)
        
        print(f"{format_time(env.now)}: {order.name} in service centers")
        order.exit_time = env.now

        # 模拟服务耗时
        yield env.timeout(order.prep_time)

        waiting_time = order.exit_time - order.placement_time
        print(f"{format_time(env.now)}: {order.name} exited at {env.now:.3f} minutes. Waiting time: {waiting_time:.3f} minutes.")
        waiting_times.append(waiting_time)

这个方案无需额外同步对象,逻辑简洁直接:先拿订单,时间不够就等,时间到了再处理。

方案2:用Condition监听条件触发

如果需要严格“只有满足条件时才获取订单”,可以用Condition对象,在有订单入队或时间到达阈值时,唤醒服务进程检查条件:

def process_orders(env, order_queue, condition):
    while True:
        # 等待条件触发(有新订单入队 或 时间到了某个订单的start_prep)
        yield condition.wait()
        
        # 批量处理所有符合条件的订单
        while order_queue.items and (round(env.now, 5) >= round(order_queue.items[-1].start_prep, 5)):
            order = order_queue.get()
            print(f"{format_time(env.now)}: {order.name} in service centers")
            order.exit_time = env.now

            yield env.timeout(order.prep_time)

            waiting_time = order.exit_time - order.placement_time
            print(f"{format_time(env.now)}: {order.name} exited at {env.now:.3f} minutes. Waiting time: {waiting_time:.3f} minutes.")
            waiting_times.append(waiting_time)

# 主流程初始化
env = simpy.Environment()
order_queue = simpy.Store(env)
condition = simpy.Condition(env)

# 生成订单的进程中,每次放入订单后通知Condition
def generate_orders(env, order_queue, condition):
    for i in range(10):
        order = Order(name=f"Order {i}", placement_time=env.now, start_prep=env.now + 2, prep_time=1)
        yield order_queue.put(order)
        condition.notify()  # 通知服务进程有新订单
        yield env.timeout(1)

# 启动进程
env.process(process_orders(env, order_queue, condition))
env.process(generate_orders(env, order_queue, condition))
env.run()

关键提醒

永远不要在SimPy进程中写没有yield的无限循环——这会直接卡死整个事件循环。所有需要等待的逻辑都必须通过yield事件(比如timeout、Store.get()、Condition.wait()等)实现,让SimPy的事件调度器有机会处理其他进程的事件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:27:46