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。