Główną różnicą jest to, że Lock
można uzyskać tylko raz. Nie można go uzyskać ponownie, dopóki nie zostanie zwolniony. (Po wydaniu może być ponownie acaquired przez dowolny wątek).
Z drugiej strony, RLock
można uzyskać wiele razy, za pomocą tego samego wątku. Musi być wydany tyle samo razy, aby zostać "odblokowanym".
Kolejną różnicą jest to, że nabyta Lock
może zostać zwolniona przez dowolny wątek, podczas gdy nabyta RLock
może zostać zwolniona tylko przez wątek, który ją nabył.
Oto przykład demostracji, dlaczego czasami przydatne jest użycie RLock
. Załóżmy, że masz:
def f():
g()
h()
def g():
h()
do_something1()
def h():
do_something2()
Powiedzmy, wszystkie f
g
i h
są publicznego (to może być wywoływane bezpośrednio przez zewnętrznego wywołującego), a wszystkie z nich wymagają synchronizację.
Korzystanie z Lock
, można zrobić coś takiego:
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()
Zasadniczo, ponieważ f
nie można nazwać g
po nabyciu blokadę, musi zadzwonić do „surowego” wersję g
(tj _g
). Tak więc kończy się wersja "zsynchronizowana" i "surowa" wersja każdej funkcji.
Korzystanie RLock
elegancko rozwiązuje problem:
lock = RLock()
def f():
with lock:
g()
h()
def g():
with lock:
h()
do_something1()
def h():
with lock:
do_something2()