我相信问题的出现是因为发布引用了一个特定的请求,但该请求此时已经被新的请求覆盖了。 resource_req 是请求,但在释放之前,它会被新的resource_req 覆盖。我相信,当您尝试释放这个新请求时,它不会正确释放它,因为它不是由资源处理的释放(它是新的)。
我不知道解决方案是什么。我偶然发现这篇文章试图找到它,因为我自己也遇到了同样的问题。一个明显的可能性(我还没有尝试过)是创建一个请求列表,并跟踪它们,但这似乎是一个愚蠢的解决方案。必须有一种方法可以简单地释放资源(这是所需的行为)。如果我弄清楚了,我会尝试回复!
这是一个最小的工作示例:
import simpy
class Machine:
def __init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
def load(self,env):
"Load machine 1 when it's empty"
while True:
self.req = self.machine.request()
print("Waiting for machine at %d" %env.now)
yield self.req
print("Load machine at %d" %env.now)
self.process_proc = env.process(self.process(env))
def process(self,env):
"Machine does process and is then emptied"
print("Machine starts process at %d" %env.now)
yield env.timeout(10)
print("Machine finished process at %d" %env.now)
self.machine.release(self.req)
print("Machine released at %d" %env.now)
env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)
这里有一台机器不断尝试加载,但等待其空载。加载后,它会尝试运行 10 秒的进程,然后释放资源以允许再次加载。在 100 个时间步长中,它显然应该能够生成 10 个批次,但只完成了第一个批次。
>>>
Waiting for machine at 0
Load machine at 0
Waiting for machine at 0
Machine starts process at 0
Machine finished process at 10
Machine released at 10
>>>
看来发布不起作用,因为它指的是第二个请求。诊断此问题可以找到解决方法,但最好知道正确的方法!
一种可能的解决方案是仅释放当前用户而不是特定请求:
import simpy
class Machine:
def __init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
def load(self,env):
"Load machine 1 when it's empty"
while True:
print("Waiting for machine at %d" %env.now)
yield self.machine.request()
print("Load machine at %d" %env.now)
self.process_proc = env.process(self.process(env))
def process(self,env):
"Machine does process and is then emptied"
print("Machine starts process at %d" %env.now)
yield env.timeout(10)
print("Machine finished process at %d" %env.now)
if len(self.machine.users)>=1: self.machine.release(self.machine.users[0])
print("Machine released at %d" %env.now)
env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)
其行为符合预期,并且优点是您不需要为请求提供变量。的释放
self.machine.release(self.machine.users[0])
可能就足够了,除非您面临发布尚未请求的内容的风险。
更新基于斯特凡·舍夫克的 https://stackoverflow.com/users/3564517/stefan-scherfke注释,是将 req 显式传递给新进程:
import simpy
class Machine:
def __init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
def load(self,env):
"Load machine 1 when it's empty"
while True:
print("Waiting for machine at %d" %env.now)
req = self.machine.request()
yield req
print("Load machine at %d" %env.now)
self.process_proc = env.process(self.process(env,req))
def process(self,env,req):
"Machine does process and is then emptied"
print("Machine starts process at %d" %env.now)
yield env.timeout(10)
print("Machine finished process at %d" %env.now)
self.machine.release(req)
print("Machine released at %d" %env.now)
env = simpy.Environment()
M1 = Machine(env)
env.run(until=100)
这确实按预期工作。