使用回调开始简单模拟 运行
Starting a simpy simulation run using a callback
如何从回调中编写一些模拟代码(包括等待事件)?
将我的过程简化为最简单的示例,我想在我的简单模拟中发生事件时启动一些可执行代码。我所做的是将该可执行代码设置为事件的回调。该可执行代码本身有一些简单的事件处理,特别是超时。在我的真实代码中,这发生在一个进程中,但是这个简化版本,其中 event
在 main 中显示相同的问题行为:
import simpy
if __name__ == '__main__':
env = simpy.Environment()
def simulationRun(event):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
event = env.timeout(5)
event.callbacks.append(simulationRun)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
我的预期输出是:
Starting simulation.
Starting a run at time [5]
Ending a run at time [10]
End of simulation.
然而,我的实际输出是:
Starting simulation.
End of simulation.
当我删除 yield 命令时,我得到:
Starting simulation.
Starting a run at time [5]
Ending a run at time [5]
End of simulation.
显然回调设置正确,但重点是模拟 simulationRun
中的超时。我如何在回调代码中 运行 一些模拟代码(包括等待事件)?
这使用 Python 3.4.2 和 simpy。
问题在于回调不是进程,因此在 simpy 模拟引擎中它不是 运行 可以由引擎停止和重新启动的方式。你需要的是一个过程。您可以通过从单独的回调函数启动该代码来使当前 simulationRun
成为一个进程,如下所示。
import simpy
if __name__ == '__main__':
env = simpy.Environment()
def simulationRun():
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
def callback(event):
s = simulationRun()
env.process(s)
event = env.timeout(5)
event.callbacks.append(callback)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
您不应直接使用回调。最佳做法是使用另一个
为您启动 simulation_run()
的进程:
import simpy
def simulation_run(env):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
def starter(env):
yield env.timeout(5)
env.process(simulation_run(env))
if __name__ == '__main__':
env = simpy.Environment()
env.process(starter(env))
print("Starting simulation.")
env.run(20)
print("End of simulation.")
由于这是一个相对常见的模式,我们在其中内置了一个效用函数
SimPy 正是这样做的:
import simpy
import simpy.util
def simulation_run(env):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
if __name__ == '__main__':
env = simpy.Environment()
simpy.util.start_delayed(env, simulation_run(env), delay=5)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
注意:您应该始终将对环境的引用传递到您的进程中
而不是使用全局范围内的那个。这可能看起来很乏味,但你
如果您稍后重组或重构您的代码,可以 运行 遇到任何类型的问题
并且全局环境不再是您所期望的或不再可用。
如何从回调中编写一些模拟代码(包括等待事件)?
将我的过程简化为最简单的示例,我想在我的简单模拟中发生事件时启动一些可执行代码。我所做的是将该可执行代码设置为事件的回调。该可执行代码本身有一些简单的事件处理,特别是超时。在我的真实代码中,这发生在一个进程中,但是这个简化版本,其中 event
在 main 中显示相同的问题行为:
import simpy
if __name__ == '__main__':
env = simpy.Environment()
def simulationRun(event):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
event = env.timeout(5)
event.callbacks.append(simulationRun)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
我的预期输出是:
Starting simulation.
Starting a run at time [5]
Ending a run at time [10]
End of simulation.
然而,我的实际输出是:
Starting simulation.
End of simulation.
当我删除 yield 命令时,我得到:
Starting simulation.
Starting a run at time [5]
Ending a run at time [5]
End of simulation.
显然回调设置正确,但重点是模拟 simulationRun
中的超时。我如何在回调代码中 运行 一些模拟代码(包括等待事件)?
这使用 Python 3.4.2 和 simpy。
问题在于回调不是进程,因此在 simpy 模拟引擎中它不是 运行 可以由引擎停止和重新启动的方式。你需要的是一个过程。您可以通过从单独的回调函数启动该代码来使当前 simulationRun
成为一个进程,如下所示。
import simpy
if __name__ == '__main__':
env = simpy.Environment()
def simulationRun():
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
def callback(event):
s = simulationRun()
env.process(s)
event = env.timeout(5)
event.callbacks.append(callback)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
您不应直接使用回调。最佳做法是使用另一个
为您启动 simulation_run()
的进程:
import simpy
def simulation_run(env):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
def starter(env):
yield env.timeout(5)
env.process(simulation_run(env))
if __name__ == '__main__':
env = simpy.Environment()
env.process(starter(env))
print("Starting simulation.")
env.run(20)
print("End of simulation.")
由于这是一个相对常见的模式,我们在其中内置了一个效用函数 SimPy 正是这样做的:
import simpy
import simpy.util
def simulation_run(env):
print("Starting a run at time [%i]" % env.now)
yield env.timeout(5)
print("Ending a run at time [%i]" % env.now)
if __name__ == '__main__':
env = simpy.Environment()
simpy.util.start_delayed(env, simulation_run(env), delay=5)
print("Starting simulation.")
env.run(20)
print("End of simulation.")
注意:您应该始终将对环境的引用传递到您的进程中 而不是使用全局范围内的那个。这可能看起来很乏味,但你 如果您稍后重组或重构您的代码,可以 运行 遇到任何类型的问题 并且全局环境不再是您所期望的或不再可用。