[Python 多线程] RLock可重入锁 (九)
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。