docs から:
threading.RLock()-新しいリエントラントロックオブジェクトを返すファクトリ関数。再入可能なロックは、それを取得したスレッドによって解放される必要があります。スレッドがリエントラントロックを取得すると、同じスレッドがブロックせずに再度ロックを取得できます。スレッドは、取得するたびに一度解放する必要があります。
なぜこれが必要なのか分かりませんか? Rlock
とLock
の違いは何ですか?
主な違いは、Lock
は1回しか取得できないことです。リリースされるまで、再度取得することはできません。 (リリース後、どのスレッドでも再取得できます)。
一方、RLock
は、同じスレッドで複数回取得できます。 「ロック解除」するには、同じ回数だけリリースする必要があります。
別の違いは、取得したLock
はどのスレッドでも解放できるのに対し、取得したRLock
はそれを取得したスレッドのみが解放できることです。
以下は、RLock
が時々役立つ理由を示す例です。あなたが持っていると仮定します:
def f():
g()
h()
def g():
h()
do_something1()
def h():
do_something2()
f
、g
、およびh
のすべてがpublic(つまり、外部の呼び出し元から直接呼び出すことができる)であり、それらすべてが同期が必要です。
Lock
を使用すると、次のようなことができます。
lock = Lock()
def f():
with lock:
_g()
_h()
def g():
with lock:
_g()
def _g():
_h()
do_something1()
def h():
with lock:
_h()
def _h():
do_something2()
基本的に、f
はロックの取得後にg
を呼び出すことができないため、g
の「生の」バージョンを呼び出す必要があります(つまり、_g
)。したがって、各機能の「同期」バージョンと「生」バージョンになります。
RLock
を使用すると、問題をエレガントに解決できます。
lock = RLock()
def f():
with lock:
g()
h()
def g():
with lock:
h()
do_something1()
def h():
with lock:
do_something2()