【学习笔记】SimPy 学习(五):SimPy 版本迁移
SimPy 版本迁移:SimPy 2 -> SimPy 3 -> SimPy 4
API Reference
SimPy 2 to 3
Imports
SimPy 3 的 import
被简化。SimPy 2 需要根据模拟环境选择需要导入的模块,SimPy 3 大部分情况下只用导入 simpy
1 2 from Simpy.Simulation import Simulation, Process, hold
Simulation* classes
SimPy 3 的 Environment
替换 Simulation
,RealtimeEnvironment
替换 SimulationRT
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from SimPy.Simulation import initialize, simulateinitialize() simulate(until=10 ) from SimPy.Simulation import Simulationsim = Simulation() sim.simulate(until=10 )
1 2 3 4 5 6 import simpyenv = simpy.Environment() env.run(until=10 )
Defining a Process
SimPy 3 中的 Process 是一个封装在进程实例中的 Python 生成器(无论它是在模块级定义的还是作为实例方法定义的)。生成器通常需要对环境的引用才能与之交互,但这是可选的。
进程可以通过创建一个进程实例并将生成器传递给它来启动。环境为此提供了一个快捷方式:process()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from Simpy.Simulation import Processclass MyProcess (Process ): def __init__ (self, another_param ): super ().__init__() self.another_param = another_param def generator_function (self ): """Implement the process' behavior.""" yield something initialize() proc = Process('Spam' ) activate(proc, proc.generator_function()) from SimPy.Simulation import Simulation, Processclass MyProcess (Process ): def __init__ (self, sim, another_param ): super ().__init__(sim=sim) self.another_param = another_param def generator_function (self ): """Implement the process' behaviour.""" yield something sim = Simulation() proc = Process(sim, 'Spam' ) sim.activate(proc, proc.generator_function())
1 2 3 4 5 6 7 8 9 import simpydef generator_function (env, another_param ): """Implement the process' behavior.""" yield something env = simpy.Environment() proc = env.process(generator_function(env, 'Spam' ))
SimPy Keywords
SimPy 3中,可以直接生成事件。可以直接实例化事件,也可以使用 Environment 提供的快捷方式。
通常,每当一个进程产生一个事件时,该进程的执行都会被挂起,并在事件被触发后重新开始。为了激发这种理解,一些活动被重新命名。例如,hold
关键字意味着等待一段时间。就事件而言,这意味着发生了超时。因此,hold
已被 Timeout
事件取代。
1 2 3 4 5 6 7 8 9 10 yield hold, self, durationyield passivate, selfyield request, self, resourceyield release, self, resourceyield waitevent, self, eventyield waitevent, self, [event_a, event_b, event_c]yield queueevent, self, event_listyield get, self, level, amountyield put, self, level, amount
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 yield env.timeout(duration) yield env.event() yield resource.request() resource.release() yield event yield env.all_of([event_a, event_b, event_c]) yield env.any_of([event_a, event_b, event_c]) yield container.get(amount) yield container.put(amount)yield event_a | event_b yield event_a & event_b yield env.process(calculation(env))
Interrupts
SimPy 3 中,可以对进程调用 interrupt()
。一个中断被抛出到进程中,进程必须通过 try...except simpy.Interrupt
处理中断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Interrupter (Process ): def __init__ (self, victim ): super ().__init__() self.victim = victim def run (self ): yield hold, self, 1 self.interrupt(self.victim_proc) self.victim_proc.interruptCause = 'Spam' class Victim (Process ): def run (self ): yield hold, self, 10 if self.interrupted: cause = self.interruptCause self.interruptReset()
1 2 3 4 5 6 7 8 9 10 def interrupter (env, victim_proc ): yield env.timeout(1 ) victim_proc.interrupt('Spam' ) def victim (env ): try : yield env.timeout(10 ) except Interrupt as interrupt: cause = interrupt.cause
SimPy 3 to 4
Python >= 3.6
Environment Subclasses
BaseEnvironment
类已在 SimPy 4 中移除。Environment
类现在是最基本的类。任何从 BaseEnvironment
继承的代码都应该修改为从 Environment
继承。
1 2 3 4 5 6 7 class MyEnv (SimPy.BaseEnvironment): ... class MyEnv (SimPy.Environment): ...
Returning from Process Generators
在下面的示例中,Environment.exit()
用于返回 the first needle。当将 SimPy 3 与 Python 2 一起使用时,这是从流程生成器返回值的唯一方法。
1 2 3 4 5 6 7 8 9 def find_first_needle (env, store ): while True : item = yield store.get() if is_needle(item): env.exit(item) def proc (env, store ): needle = yield env.process(find_first_needle(env, store))
在 SimPy 4 与 Python 3 下,可以写为:
1 2 3 4 5 def find_first_needle (env, store ): while True : item = yield store.get() if is_needle(item): return item
SimPy 学习