在simpy中触发进程的默认顺序似乎依赖于它们的创建顺序?我想明确地对流程进行排名,以便按照精确的顺序触发,无论它们何时被创建。如果你需要一个例子,这里有3个过程的模拟:吃食物,补充板,移除板。 eat()
进程会触发plateEmpty
事件,期望重新填充该事件。但是如果removePlate()
进程发生在refillPlate()
之前,那么重新填充就不会发生。我想要先重新装满。我可以执行的唯一方法是订购44和45号线。还有另外一种方法吗?
[PS:我知道优先资源,但这不是我想要的。]
import simpy
env = simpy.Environment()
plateEmpty = env.event()
plateGone = env.event()
scoop = 5
def eat(env):
global plateEmpty
global food
while True:
e = yield env.timeout(5) | plateGone
if plateGone in e:
print "Ack! my plate is gone." #bad
break
if food > 0:
food -= 1 # one bite
print env.now,"took a bite"
if food == 0:
plateEmpty.succeed("I want more food")
def refillPlate(env):
global food
global plateEmpty
while True:
e = yield plateEmpty | plateGone
if plateGone in e:
print env.now, "cannot refill."
break
food += scoop
print env.now,"refilled plate"
plateEmpty = env.event() # reset trigger
def removePlate(env):
while True:
e = yield plateEmpty | plateGone
if plateEmpty not in e: continue # trigger was reset
print env.now,"removed plate"
plateGone.succeed()
break
food = scoop
env.process(eat(env))
env.process(removePlate(env)) # line 44: want this triggered last
env.process(refillPlate(env)) # line 45: want this triggered first
env.run(until=100)
答案 0 :(得分:0)
我找到了两个解决方案。
解决方案1:
def removePlate(env):
while True:
e = yield plateEmpty | plateGone
yield env.timeout(0.00001)
if plateEmpty not in e: continue # trigger was reset
print(env.now,"removed plate")
plateGone.succeed()
break
解决方案2:
import simpy
env = simpy.Environment()
plateEmpty = env.event()
plateGone = env.event()
scoop = 5
condition = None
def eat(env):
global plateEmpty
global food
while True:
e = yield env.timeout(5) | plateGone
if plateGone in e:
print("Ack! my plate is gone.") #bad
break
if food > 0:
food -= 1 # one bite
print(env.now,"took a bite")
if food == 0:
plateEmpty.succeed("I want more food")
def refillPlate(env):
global food
global plateEmpty
global condition
while True:
condition = plateEmpty | plateGone
e = yield condition
if plateGone in e:
print(env.now, "cannot refill.")
break
food += scoop
print(env.now,"refilled plate")
plateEmpty = env.event() # reset trigger
def removePlate(env):
global spec_proc
while True:
e = yield plateEmpty | plateGone
# Check if the other process is scheduled to run at the same time
if (env.now, condition) in [(time, condition) for time, _, _, condition in env._queue]:
yield env.timeout(0.00001)
if plateEmpty not in e: continue # trigger was reset
print(env.now,"removed plate")
plateGone.succeed()
break
food = scoop
env.process(eat(env))
spec_proc = env.process(removePlate(env)) # line 44: want this triggered last
env.process(refillPlate(env)) # line 45: want this triggered first
env.run(until=100)