Python multi threaded programming (vi) : reentrant lock RLock

  • 2020-05-05 11:25:31
  • OfStack

Consider the situation: what if a thread encounters lock nesting, which is when a thread needs to fetch a critical resource again.

In this case, the code looks like this:


'''
Created on 2012-9-8
 
@author: walfred
@module: thread.ThreadTest6
''' 
 
import threading 
import time 
 
counter = 0 
mutex = threading.Lock() 
 
class MyThread(threading.Thread): 
    def __init__(self): 
        threading.Thread.__init__(self) 
 
    def run(self): 
        global counter, mutex 
        time.sleep(1); 
        if mutex.acquire(): 
            counter += 1 
            print "I am %s, set counter:%s" % (self.name, counter) 
            if mutex.acquire(): 
                counter += 1 
                print "I am %s, set counter:%s" % (self.name, counter) 
                mutex.release() 
            mutex.release() 
 
if __name__ == "__main__": 
    for i in range(0, 200): 
        my_thread = MyThread() 
        my_thread.start()

The code for this case runs as follows:


I am Thread-1, set counter:1

After that, it simply hangs, which makes for the simplest deadlock.

Is there a situation where a thread can access a competing resource again using a mutex? In Python, to support multiple requests for the same resource in the same thread, python provides a "reentrant lock" : threading.RLock. This RLock maintains an Lock and an counter variable internally, and counter records the number of acquire, so that the resource can be require multiple times. Until all the acquire of one thread are release, the other thread cannot get the resource. In the above example, if RLock is used instead of Lock, a deadlock does not occur:

The code simply puts the above:


mutex = threading.Lock()

Replace with:

mutex = threading.RLock()

Can.


Related articles: