如何在simpy进程回调上设置优先级? [英] how can I set priority on simpy process callbacks?
问题描述
在simpy中触发进程的默认顺序似乎取决于它们的创建顺序?我想明确地对流程进行排名,以便以精确的顺序触发,而不管它们是何时创建的.如果您需要一个示例,下面是一个包含3个过程的模拟:吃食物,重新装满盘子,取下盘子. eat()
进程触发plateEmpty
事件,期望重新填充该事件.但是,如果removePlate()
进程发生在refillPlate()
之前,则不会发生重新填充.我希望笔芯总是首先发生.而我可以执行的唯一方法是对第44行和第45行进行排序.还有另一种方法吗?
The default order in which processes are triggered in simpy seems to rely on the order they were created? I want to expressly rank processes so they are triggered in a precise order, regardless of when they were created. If you need an example, here's a simulation with 3 processes: eat food, refill plate, remove plate. the eat()
process triggers the plateEmpty
event, expecting it to be refilled. But if the removePlate()
process happens before refillPlate()
, then refill can't happen. I want refill to always happen first. And the only way I can enforce that is ordering lines 44 and 45. Is there another way?
[PS:我了解优先资源,但这不是我想要的.]
[PS: I know about priority resources, but that's not what I want.]
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)
推荐答案
我为此找到了两种解决方案.
I find two solutions for this.
- 引入一个小的延迟. (根据进程之间的优先级来缩放延迟.)
- 检查队列中是否有特定条件,并先对其进行处理.
解决方案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)
这篇关于如何在simpy进程回调上设置优先级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!