python多线程的可重入锁

2020年5月14日 / 15次阅读 / Last Modified 2020年5月14日
多线程

可重复锁(Reentrant Lock),有人也之为递归锁,不过递归锁这个名字有点狭义。python多线程可重入锁就是threading.RLock对象。

可重入锁的使用场景:

可重入锁与一般的互斥锁一样,都是用来同步线程对共享资源的访问。不过有的时候,同一个线程在获取锁之后,还有可能再次去获取相同的锁。这可能是代码内有递归,也可能是用一把锁保护了好几个不同的共享资源,而这些不同的共享资源可以分别乱序获取。可重入锁在这时就可能发挥作用,它允许线程多次获取同一把锁。这样做事为了防止死锁的放生,如果是普通的Lock,同一个线程在第2次获取时,就死锁了。

可重入锁在使用的时候,要注意申请和释放锁的动作要对称。

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire():  
            mutex.acquire()
            num += 1
            msg = self.name+' set num to '+str(num)
            print(msg)
            mutex.release()
            mutex.release()

num = 0
mutex = threading.RLock()

def test():
    for i in range(5):
        t = MyThread()
        t.start()

if __name__ == '__main__':
    test()

以上代码,每个线程都连续acquire了两次锁,最后也是释放了两次锁!如果不同RLock,而是使用普通的Lock,这段代码就死锁了。运行结果如下:

D:\py>python rlock.py
Thread-5 set num to 1
Thread-3 set num to 2
Thread-1 set num to 3
Thread-4 set num to 4
Thread-2 set num to 5

python官方有关于RLock有一段说明:

A reentrant lock is a synchronization primitive that may be acquired multiple times by the same thread. Internally, it uses the concepts of “owning thread” and “recursion level” in addition to the locked/unlocked state used by primitive locks. In the locked state, some thread owns the lock; in the unlocked state, no thread owns it. To lock the lock, a thread calls its acquire() method; this returns once the thread owns the lock. To unlock the lock, a thread calls its release() method. acquire()/release() call pairs may be nested; only the final release() (the release() of the outermost pair) resets the lock to unlocked and allows another thread blocked in acquire() to proceed.

注意可重入锁对应的owning thread和recursion level这两个概念。

-- EOF --

本文链接:https://www.pynote.net/archives/1913

留言区

电子邮件地址不会被公开。 必填项已用*标注


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top