リリースが特定のリクエストを参照しているため、問題が発生したと思いますが、そのリクエストはそれまでに新しいリクエストによって上書きされています。resource_req はリクエストですが、解放される前に、新しい resource_req によって上書きされます。この新しいリクエストをリリースしようとしても、適切にリリースされないと思います。これは、リソースによって処理されているリリースではないためです (新しいリクエストです)。
解決策が何であるかわかりません。私自身も同じ問題を抱えているので、見つけようとしてこの投稿に出くわしました。明白な可能性の 1 つ (私はまだ試していません) は、リクエストのリストを作成してそれらを追跡することですが、これはばかげた解決策のように思えます。リソースを単純に解放する方法が必要です (これが望ましい動作です)。分かり次第追記しようと思います!
最小限の作業例を次に示します。
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 バッチを作成できるはずですが、最初の 1 つだけが実行されます。
>>>
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
>>>
2番目のリクエストを参照しているため、リリースが機能していないようです。これを診断することで回避策を見つけることができますが、それを行う正しい方法を知っておくとよいでしょう!
考えられる解決策の 1 つは、特定の要求ではなく、現在のユーザーを解放することです。
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])
まだリクエストされていないものをリリースするリスクがない限り、おそらく十分です。
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)
これは確かに期待どおりに機能します。