Buf*_*lls 54 python multithreading locking reentrancy
来自文档:
threading.RLock() - 一个返回新的可重入锁对象的工厂函数.必须由获取它的线程释放可重入锁.一旦线程获得了可重入锁,同一个线程可以再次获取它而不会阻塞; 线程必须在每次获取它时释放一次.
我不知道为什么我们需要这个?Rlock和之间有什么区别Lock?
shx*_*hx2 112
主要区别在于a Lock只能获得一次.在它被释放之前不能再获得它.(在它发布之后,它可以被任何线程重新获得).
一个RLock在另一方面,可以由同一个线程来获取多次.它需要被释放相同的次数才能被"解锁".
另一个区别是获取Lock的任何线程都可以释放,而获取的RLock只能由获取它的线程释放.
这是一个示例,说明为什么RLock有时有用.假设你有:
def f():
g()
h()
def g():
h()
do_something1()
def h():
do_something2()
Run Code Online (Sandbox Code Playgroud)
比方说,所有的f,g以及h被公众(即可以直接由外部调用程序调用),和所有的人都需要同步化.
使用a Lock,您可以执行以下操作:
lock = Lock()
def f():
with lock:
_g()
_h()
def g():
with lock:
_g()
def _g():
_h()
do_something1()
def h():
with lock:
_h()
def _h():
do_something2()
Run Code Online (Sandbox Code Playgroud)
基本上,由于在获取锁之后f无法调用g,因此需要调用g(原始)版本(即_g).所以你最终会得到一个"同步"版本和每个函数的"原始"版本.
使用RLock优雅解决问题:
lock = RLock()
def f():
with lock:
g()
h()
def g():
with lock:
h()
do_something1()
def h():
with lock:
do_something2()
Run Code Online (Sandbox Code Playgroud)
Kri*_*ris 15
要扩展 shx2 的答案,您想使用一个与另一个的原因可能如下:
常规Lock(互斥锁)通常更快更安全。
使用的原因RLock是为了避免由于例如递归而导致的死锁。例如,让我们在递归阶乘函数中加锁。(诚然有些做作)
from threading import Lock
lock = Lock()
def factorial(n):
assert n > 0
if n == 1:
return 1
with lock:
out = n * factorial(n - 1)
return out
Run Code Online (Sandbox Code Playgroud)
由于递归调用,该函数会导致死锁。RLock但是,如果我们改为使用,递归调用可以根据需要多次重新输入相同的锁。因此名称可重入(或递归)锁。