[Python 多线程] RLock可重入锁 (九)

时间:2022-06-03 19:28:22

RLock

可重复锁,是线程相关的锁。同样是线程相关的还有threading.local。

线程A获得可重用锁,并可以多次成功获取,不会阻塞。最后要再线程A中和acquire次数相同的release。

例1:

import threading

lock = threading.Lock()

lock.acquire()

ret = lock.acquire()
print(1,ret) 运行结果:
阻塞中

  在主线程中,使用阻塞锁加锁后,再次获取锁就阻塞了,比如第一个锁释放掉才可以获取。

例2:

import threading

lock = threading.Lock()

lock.acquire()

ret = lock.acquire(False)
print(1,ret) 运行结果:
1 False

  使用非阻塞锁获取,返回False,表示没有获取到锁。

例3:

import threading

lock = threading.RLock()

ret = lock.acquire()
print(ret)
ret = lock.acquire()
print(ret) 运行结果:
True
True

  使用RLock可重入锁,第一个锁没有释放,第二个也能获取到锁。

例4:

import threading

lock = threading.RLock()

ret = lock.acquire()
print(ret)
ret = lock.acquire(timeout=3)
print(ret)
ret = lock.acquire(True)
print(ret)
ret = lock.acquire(False)
print(ret) lock.release()
lock.release()
lock.release()
lock.release() 运行结果:
True
True
True
True

  与acquire相应次数的release释放。

例5:

import threading

lock = threading.RLock()

ret = lock.acquire()
print(ret)
ret = lock.acquire(timeout=3)
print(ret)
ret = lock.acquire(True)
print(ret)
ret = lock.acquire(False)
print(ret) lock.release()
lock.release()
lock.release()
lock.release()
lock.release() #多release一次 运行结果:
True
True
True
True
Traceback (most recent call last):
File "C:/python/test.py", line 18, in <module>
lock.release()
RuntimeError: cannot release un-acquired lock

  但只要多一个release就会抛RuntimeError异常,提示无法释放一个un-acquire的锁。

例6:

import threading

lock = threading.RLock()

def subThread(lock:threading.RLock):
lock.release() ret = lock.acquire()
print(ret)
ret = lock.acquire(timeout=3)
print(ret)
ret = lock.acquire(True)
print(ret)
ret = lock.acquire(False)
print(ret) t = threading.Thread(target=subThread,args=(lock,))
t.start() 运行结果:
True
True
True
True
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:/python/test.py", line 6, in subThread
lock.release()
RuntimeError: cannot release un-acquired lock

  acquire是在主线程获取了四个,新起了一次子线程,在子线程中release,抛出RuntimeError异常,说明RLock是线程级别的,在哪个线程acquire的,就需要在这个线程release,其它无法release。也就是说RLock无法跨线程。需要跨线程就得使用Lock。