我试图在SimPy模拟中向各种事件添加回调,我发现你不能在回调中使用yield
关键字。有没有办法正确地执行此操作,还是只需要在回调中使用回调?
例如,我希望put_and_get_eggs
函数可以在以下代码中使用:
import simpy
env = simpy.Environment()
foods = simpy.FilterStore(env)
foods.items = ['spam', 'eggs', 'eggs']
def test_callback(env):
print("starting")
yield foods.get(lambda x: x == "spam") & foods.get(lambda x: x == "eggs")
yield env.timeout(5)
print("items after first get using AllOf: %s" % foods.items)
t1, t2 = foods.get(lambda x: x == "spam"), foods.get(lambda x: x == "eggs")
# add callbacks to the get event. This works
t1.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
t2.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
yield env.timeout(1)
# Spam is put into the environment after 1 second, then immediately the callback gets called on get event
foods.put("spam")
print("spam put at %s" % env.now)
put_eggs = foods.put("eggs")
# add callbacks that include a yield, this doesn't work
def get_and_put_eggs():
print("getting eggs in callback with yield")
yield foods.get('eggs')
print("getting eggs in callback with yield")
yield env.timeout(5)
print("getting eggs in callback with yield")
yield foods.put('eggs')
print("getting eggs in callback with yield")
put_eggs.callbacks.append(get_and_put_eggs)
proc = env.process(test_callback(env))
env.run()
到目前为止,我能够通过定义" yield"右边的每个事件来实现这一点。在get_and_put_eggs
中作为一个单独的事件并向它们添加回调,但这会创建一个非常长且令人困惑的回调链。我希望能够执行类似yield from
的操作,但我无法使其工作(例如使用行put_eggs.callbacks.append(lambda x: (yield from get_and_put_eggs))
)。
这可能吗?我检查了以下问题,但在回调场景中似乎有点不同,因为回调仅附加到回调列表,您无法从中明确屈服。 Python, SimPy: Using yield inside functions
答案 0 :(得分:1)
你永远不应该直接将anythig附加到回调中,特别是产生功能只是不起作用。
相反,只需生成一个新的子进程,让它等待(yield)你要追加回调的事件。
答案 1 :(得分:0)
@Stefan我实际上可以通过在回调中添加一个env.process来获得这项工作:
import simpy
env = simpy.Environment()
foods = simpy.FilterStore(env)
foods.items = ['spam', 'eggs', 'eggs']
def test_callback(env):
print("starting")
yield foods.get(lambda x: x == "spam") & foods.get(lambda x: x == "eggs")
yield env.timeout(5)
print("items after first get using AllOf: %s" % foods.items)
t1, t2 = foods.get(lambda x: x == "spam"), foods.get(lambda x: x == "eggs")
# add callbacks to the get event. This works
t1.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
t2.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
yield env.timeout(1)
# Spam is put into the environment after 1 second, then immediately the callback gets called on get event
foods.put("spam")
print("spam put at %s" % env.now)
put_eggs = foods.put("eggs")
# add callbacks that include a yield, this doesn't work
def get_and_put_eggs(event):
print("getting eggs in callback with yield")
yield foods.get(lambda x: x == 'eggs')
print("getting eggs in callback with yield")
yield env.timeout(5)
print("getting eggs in callback with yield")
yield foods.put('eggs')
print("getting eggs in callback with yield")
put_eggs.callbacks.append(lambda x: env.process(get_and_put_eggs(x)))
proc = env.process(test_callback(env))
env.run()
您是否会通过生成新的子流程来澄清您的意思?你的意思是env.process?如果我希望每个衍生进程在完成后立即执行某些操作,该怎么办?那么回调似乎是必要的,但如果它们不是,你能举个例子吗?