SimPy如何循环遍历事件触发资源使用 简化多流程代码
问题
现有如下可正常运行的SimPy仿真代码:
class FA(object): def __init__(self, env): self.env = env self.resource1 = simpy.Resource(env, 10) self.resource2 = simpy.Resource(env, 20) def do_process1(self, tray): yield self.env.timeout(50) def do_process2(self, tray): yield self.env.timeout(100) def do_FA(env, fa, tray): with fa.resource1.request() as request: yield request yield env.process(fa.do_process1(tray)) with fa.resource2.request() as request: yield request yield env.process(fa.do_process2(tray)) def run_FA(env): fa = FA(env) tray = 0 while True: tray += 1 env.process(do_FA(env, fa, tray)) time_between_trays = 12 yield env.timeout(time_between_trays) env = simpy.Environment() env.process(run_FA(env)) env.run(until=20000)
其余相关逻辑省略
当前do_FA函数需要逐段编写资源申请、流程调用的逻辑,当场景需要配置数十个资源与对应处理流程时,会产生大量重复代码。需要实现可扩展的简化方案:通过创建资源与关联处理流程的映射列表,用循环遍历的方式完成串行的资源申请、流程调用逻辑,避免逐段编写重复代码。
实现方案
核心思路是把所有需要串行执行的「资源申请-流程执行」步骤按执行顺序整理成配置列表,循环遍历列表复用同一套逻辑即可,后续新增/调整步骤只需要修改配置列表,不需要改动流程执行的核心代码。
具体改造步骤
- 在
FA类初始化时,按执行顺序维护步骤配置列表,每个列表元素存储当前步骤需要占用的资源、对应的处理方法。如果其他业务逻辑需要单独引用某类资源,也可以先将资源绑定为实例属性,再加入配置列表,不影响原有其他逻辑的调用。 - 重写
do_FA生成器函数,循环遍历步骤配置列表,每一步统一执行「申请资源->等待资源分配->调用对应处理流程」的逻辑,和原有逐段编写的执行逻辑完全等价。
改造后的可运行代码如下:
import simpy class FA(object): def __init__(self, env): self.env = env # 若需要单独引用资源,可先绑定实例属性 self.resource1 = simpy.Resource(env, capacity=10) self.resource2 = simpy.Resource(env, capacity=20) # 按执行顺序配置所有步骤:(资源实例, 对应处理方法) self.steps = [ (self.resource1, self.do_process1), (self.resource2, self.do_process2), # 后续新增步骤只需要在这里追加元组即可,例如: # self.resource3 = simpy.Resource(env, capacity=5) # (self.resource3, self.do_process3), ] def do_process1(self, tray): yield self.env.timeout(50) def do_process2(self, tray): yield self.env.timeout(100) # 新增处理方法直接在这里定义,再追加到steps配置即可 # def do_process3(self, tray): # yield self.env.timeout(80) def do_FA(env, fa, tray): # 循环遍历所有步骤,复用统一逻辑 for resource, process_func in fa.steps: with resource.request() as request: yield request yield env.process(process_func(tray)) def run_FA(env): fa = FA(env) tray = 0 while True: tray += 1 env.process(do_FA(env, fa, tray)) time_between_trays = 12 yield env.timeout(time_between_trays) env = simpy.Environment() env.process(run_FA(env)) env.run(until=20000)
方案说明
- 逻辑一致性:执行逻辑和原代码完全一致,严格按配置顺序串行申请资源,上一个流程执行完成、释放对应资源后,才会申请下一个步骤的资源,不会改变原有仿真的运行结果。
- 维护成本低:新增/调整流程步骤时,只需要修改
FA类中的steps配置列表,不需要改动do_FA的核心逻辑,哪怕有数十上百个步骤也不会产生重复代码。 - 扩展性强:如果后续某一步不需要占用资源、或者需要同时申请多个资源,只需要调整配置结构、对应修改循环里的少量逻辑即可,不需要重写整个流程函数。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

