Resource Not Releasing In Simpy - What Am I Doing Wrong?
Solution 1:
I believe the problem comes about because the release refers to a specific request, but the request has by then already be over-written by a new request. resource_req is the request, but before it can be released, it is overwritten by a new resource_req. I believe that when you try to release this new request it does not release it properly, because it's not a release that is being handled by the resource (it's the new one).
I don't know what the solution is. I came across this post trying to find it, because I'm having the same problem myself. One obvious possibility (which I haven't tried yet) is to create a list of requests, and keep track of them, but this seems like a silly solution. There must be a way to simply free up the resource (which is the behaviour that is desired). I'll try to post back if I figure it out!
Here's a minimal working example:
import simpy
classMachine:
def__init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
defload(self,env):
"Load machine 1 when it's empty"whileTrue:
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))
defprocess(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)
Here there is a machine that continually tries to load, but waits for it to be empty. Once it's loaded, it tries to run a 10 second process and then releases the Resource to allow it to be loaded again. In 100 time-steps it should obviously be able to make 10 batches, but only the first one is done.
>>>
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
>>>
It seems that the release does not work, because it is referring to the second request. Diagnosing this makes it possible to find a workaround, but it would be nice to know the right way to do it!
One possible solution is to just release a current user rather than a specific request:
import simpy
classMachine:
def__init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
defload(self,env):
"Load machine 1 when it's empty"whileTrue:
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))
defprocess(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)
iflen(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)
This behaves as expected, and has the advantage that you don't need a variable for the request. The release of
self.machine.release(self.machine.users[0])
is probably sufficient, unless you're at risk of releasing something that hasn't been requested already.
Update based on Stefan Scherfke's comment, is to pass the req explicitly to the new process:
import simpy
classMachine:
def__init__(self,env):
self.machine = simpy.Resource(env,capacity=1)
self.load_proc = env.process(self.load(env))
defload(self,env):
"Load machine 1 when it's empty"whileTrue:
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))
defprocess(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)
This does indeed work as expected.
Solution 2:
Solved - there was a typo in the resource.
Originally defined as:
resource = simpy.Resource(env, 1)
Correct definition:
resource = simpy.Resource(env, capacity = 1)
Post a Comment for "Resource Not Releasing In Simpy - What Am I Doing Wrong?"