如何确保SimPy中monitor进程在每步所有foo进程后执行?
SimPy实现Monitor等待所有Foo进程完成当前时间步的正确方法
你之前监听is_alive属性的思路行不通——SimPy的事件调度基于队列执行,进程状态变化的时序没法和你的监听逻辑精准对齐。要实现「每个时间步Monitor等所有Foo干完再执行」的需求,得用事件同步,这是SimPy处理这类依赖场景的标准做法。
可运行的示例代码
import simpy def foo(env, name, sync_events): while True: # 模拟当前时间步的业务逻辑 print(f"{env.now}: 进程{name}启动当前步任务") yield env.timeout(1) # 替换为你实际的步长/工作耗时 print(f"{env.now}: 进程{name}完成当前步任务") # 生成当前步完成事件,通知Monitor done_event = simpy.Event(env) done_event.succeed() sync_events.append(done_event) # 让出执行权,等待Monitor处理完成后再进入下一轮 yield env.timeout(0) def monitor(env, foo_process_info): while True: # 收集所有Foo进程当前步的完成事件 current_step_events = [] for _, events in foo_process_info: current_step_events.extend(events) events.clear() # 清空列表,准备下一轮收集 # 先让所有Foo进程跑完当前步工作(timeout(0)触发事件队列轮转) yield env.timeout(0) # 等待所有Foo的当前步完成事件,确保全部完成才继续 yield env.all_of(current_step_events) # 执行你的Monitor核心逻辑 print(f"{env.now}: Monitor执行当前步监控操作") # 若监控逻辑有耗时,替换下面的0为实际时长 yield env.timeout(0) # 初始化SimPy环境 env = simpy.Environment() # 启动多个Foo进程(示例为3个,可按需调整) foo_process_info = [] for i in range(3): events = [] proc = env.process(foo(env, f'foo-{i}', events)) foo_process_info.append((proc, events)) # 启动Monitor进程 env.process(monitor(env, foo_process_info)) # 运行模拟到指定时间,或用env.run()无限运行 env.run(until=6)
核心逻辑说明
- Foo进程侧:每完成一个时间步的工作,就创建并触发一个「完成事件」,把事件加到共享列表中,再通过
timeout(0)把执行权交还给事件队列,让Monitor有机会处理。 - Monitor进程侧:
- 先通过
timeout(0)触发事件队列轮转,让所有Foo进程先完成当前步工作并生成事件。 - 用
env.all_of()等待所有Foo的完成事件——这一步是核心,确保所有Foo都完成当前步后才会执行监控逻辑。 - 执行监控操作后,进入下一轮循环,重复上述流程。
- 先通过
预期输出效果
0: 进程foo-0启动当前步任务 0: 进程foo-1启动当前步任务 0: 进程foo-2启动当前步任务 1: 进程foo-0完成当前步任务 1: 进程foo-1完成当前步任务 1: 进程foo-2完成当前步任务 1: Monitor执行当前步监控操作 1: 进程foo-0启动当前步任务 1: 进程foo-1启动当前步任务 1: 进程foo-2启动当前步任务 2: 进程foo-0完成当前步任务 2: 进程foo-1完成当前步任务 2: 进程foo-2完成当前步任务 2: Monitor执行当前步监控操作 ...
这个方案能严格保证每个时间步中,Monitor的逻辑始终在所有Foo进程完成当前步之后执行,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者gameveloster
相关产品推荐
相关产品推荐

