2014-04-05 25 views
31

Z docs:Jaka jest różnica między Lock and RLock

threading.RLock() - Funkcja fabryka, która zwraca nowy obiekt blokady wklęsłego. Blokada ponownego dostępu musi zostać zwolniona przez wątek, który ją nabył. Gdy wątek uzyskał blokadę ponownego wprowadzania, ten sam wątek może uzyskać go ponownie bez blokowania; nić musi zwolnić ją raz za każdym razem, gdy ją uzyska.

Nie jestem pewien, dlaczego potrzebujemy tego? jaka jest różnica między Rlock i Lock?

dzięki

Odpowiedz

67

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 fg i hpublicznego (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()