Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Lock and RLock

From the docs:

threading.RLock() -- A factory function that returns a new reentrant lock object. A reentrant lock must be released by the thread that acquired it. Once a thread has acquired a reentrant lock, the same thread may acquire it again without blocking; the thread must release it once for each time it has acquired it.

I am not sure why do we need this? what's the difference between Rlock and Lock?

like image 893
BufBills Avatar asked Apr 05 '14 19:04

BufBills


People also ask

What is the difference between threading lock and threading RLock is that?

The main difference is that a Lock can only be acquired once. It cannot be acquired again, until it is released. (After it's been released, it can be re-acaquired by any thread). An RLock on the other hand, can be acquired multiple times, by the same thread.

What is _thread RLock?

Python _thread. RLock(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module _thread , or try the search function . Example #1.

What is lock in multithreading Python?

The condition occurs when one thread tries to modify a shared resource at the same time that another thread is modifying that resource – t​his leads to garbled output, which is why threads need to be synchronized. The threading module of Python includes locks as a synchronization tool. A lock has two states: locked.

What is a reentrant lock?

What Is a Reentrant Lock? A reentrant lock is a mutual exclusion mechanism that allows threads to reenter into a lock on a resource (multiple times) without a deadlock situation. A thread entering into the lock increases the hold count by one every time. Similarly, the hold count decreases when unlock is requested.


2 Answers

The main difference is that a Lock can only be acquired once. It cannot be acquired again, until it is released. (After it's been released, it can be re-acaquired by any thread).

An RLock on the other hand, can be acquired multiple times, by the same thread. It needs to be released the same number of times in order to be "unlocked".

Another difference is that an acquired Lock can be released by any thread, while an acquired RLock can only be released by the thread which acquired it.


Here's an example demostrating why RLock is useful at times. Suppose you have:

def f():   g()   h()  def g():   h()   do_something1()  def h():   do_something2() 

Let's say all of f, g, and h are public (i.e. can be called directly by an external caller), and all of them require syncronization.

Using a Lock, you can do something like:

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() 

Basically, since f cannot call g after acquiring the lock, it needs to call a "raw" version of g (i.e. _g). So you end up with a "synced" version and a "raw" version of each function.

Using an RLock elegantly solves the problem:

lock = RLock()  def f():   with lock:     g()     h()  def g():   with lock:     h()     do_something1()  def h():   with lock:     do_something2() 
like image 63
shx2 Avatar answered Oct 19 '22 14:10

shx2


To expand on shx2's answer, the reason why you want to use one vs the other might be the following:

A regular Lock (mutex) is typically faster and safer.

The reason for using RLock is to avoid a dead lock due to e.g. recursion. For instance, let's put a lock in the recursive factorial function. (admittedly somewhat contrived)

from threading import Lock  lock = Lock()  def factorial(n):     assert n > 0     if n == 1:         return 1          with lock:                out = n * factorial(n - 1)      return out  

This function will cause a dead lock due to the recursive call. If we use RLock instead, however, the recursive calls can reenter the same lock as many times as needed. Hence the name reentrant (or recursive) lock.

like image 27
Kris Avatar answered Oct 19 '22 14:10

Kris