如何在simpy进程回调上设置优先级? [英] how can I set priority on simpy process callbacks?

查看:221
本文介绍了如何在simpy进程回调上设置优先级?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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. 引入一个小的延迟. (根据进程之间的优先级来缩放延迟.)
  2. 检查队列中是否有特定条件,并先对其进行处理.

解决方案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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆