1. ホーム
  2. python

[解決済み】LockとRLockの違いは何ですか?

2022-02-08 16:05:24

質問

から ドキュメント :

threading.RLock() -- 。 新しいリエントラントロックオブジェクトを返すファクトリー関数です。リエントラントロックは、それを取得したスレッドによって解放されなければなりません。スレッドが一度リエントラントロックを取得すると、同じスレッドがブロックすることなく再度取得することができます。

なぜこれが必要なのか、よくわかりません。 とはどう違うのでしょうか? RlockLock ?

解決方法は?

主な違いは Lock は一度だけ取得することができます。解放されるまで、再び取得することはできません。(解放された後は、どのスレッドでも再取得が可能です)。

RLock 一方、同じスレッドから複数回取得することが可能です。 ロック解除するには、同じ回数だけ解除する必要があります。

もう一つの違いは、取得した Lock はどのスレッドからも解放されるのに対し、獲得した RLock は、それを取得したスレッドによってのみ解放される。


以下は、その理由を示す例です。 RLock が有効な場合があります。あるとします。

def f():
  g()
  h()

def g():
  h()
  do_something1()

def h():
  do_something2()

を全てとします。 f , g および h パブリック (すなわち、外部の呼び出し元から直接呼び出すことができる)、そして、それらすべては同期化を必要とします。

を使用すると 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 ). つまり、各関数の "synced" バージョンと "raw" バージョンが存在することになります。

を使用すると RLock がエレガントに解決します。

lock = RLock()

def f():
  with lock:
    g()
    h()

def g():
  with lock:
    h()
    do_something1()

def h():
  with lock:
    do_something2()