Python Lock和RLock有什么区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22885775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between Lock and RLock
提问by BufBills
From the docs:
从文档:
threading.RLock() -- A factory function that returns a new reentrant lock object. A reentrant lock must be released by the thread that acquired it. Once a thread has acquired a reentrant lock, the same thread may acquire it again without blocking; the thread must release it once for each time it has acquired it.
threading.RLock() —— 一个返回一个新的可重入锁对象的工厂函数。重入锁必须由获取它的线程释放。一旦一个线程获得了可重入锁,同一个线程就可以再次获得它而不会阻塞;线程每次获得它时都必须释放一次。
I am not sure why do we need this?
what's the difference between Rlock
and Lock
?
我不确定为什么我们需要这个?什么之间的区别Rlock
和Lock
?
采纳答案by shx2
The main difference is that a Lock
can only be acquired once. It cannot be acquired again, until it is released. (After it's been released, it can be re-acaquired by any thread).
主要区别在于 aLock
只能获得一次。它不能再次获得,直到它被释放。(释放后,可以被任何线程重新获取)。
An RLock
on the other hand, can be acquired multiple times, by the same thread. It needs to be released the same number of times in order to be "unlocked".
一个RLock
在另一方面,可以由同一个线程来获取多次。它需要被释放相同的次数才能被“解锁”。
Another difference is that an acquired Lock
can be released by any thread, while an acquired RLock
can only be released by the thread which acquired it.
另一个区别是acquireLock
可以被任何线程释放,而acquireRLock
只能被获取它的线程释放。
Here's an example demostrating why RLock
is useful at times. Suppose you have:
这是一个示例,演示了为什么RLock
有时有用。假设你有:
def f():
g()
h()
def g():
h()
do_something1()
def h():
do_something2()
Let's say all of f
, g
, and h
are public(i.e. can be called directly by an external caller), and all of them require syncronization.
比方说,所有的f
,g
和h
有公共(即可以直接由外部调用程序调用),所有这些都需要同步化。
Using a Lock
, you can do something like:
使用 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()
Basically, since f
cannot call g
after acquiring the lock, it needs to call a "raw" version of g
(i.e. _g
). So you end up with a "synced" version and a "raw" version of each function.
基本上,由于在获取锁后f
无法调用g
,因此需要调用g
(ie _g
)的“原始”版本。因此,您最终会得到每个函数的“同步”版本和“原始”版本。
Using an RLock
elegantly solves the problem:
使用一个RLock
优雅地解决了这个问题:
lock = RLock()
def f():
with lock:
g()
h()
def g():
with lock:
h()
do_something1()
def h():
with lock:
do_something2()
回答by Alperen S?zer
RLock is called a recursive lock. Basically it is a lock only holder can release. In Lock, any thread can release.
RLock 称为递归锁。基本上它是一个只有持有人才能释放的锁。在 Lock 中,任何线程都可以释放。
回答by Kris
To expand on shx2's answer, the reason why you want to use one vs the othermight be the following:
要扩展 shx2 的答案,您想使用一个与另一个的原因可能如下:
A regular Lock
(mutex) is typically faster and safer.
常规Lock
(互斥锁)通常更快更安全。
The reason for using RLock
is to avoid a dead lock due to e.g. recursion. For instance, let's put a lock in the recursive factorialfunction. (admittedly somewhat contrived)
使用的原因RLock
是为了避免由于例如递归而导致的死锁。例如,让我们在递归阶乘函数中加锁。(诚然有些做作)
from threading import Lock
lock = Lock()
def factorial(n):
lock.acquire()
if n == 1:
out = 1
out = n * factorial(n - 1)
lock.release()
return out
This function will cause a dead lock due to the recursive call. If we use RLock
instead, however, the recursive calls can reenter the same lock as many times as needed. Hence the name reentrant(or recursive) lock.
由于递归调用,该函数会导致死锁。RLock
但是,如果我们改为使用,递归调用可以根据需要多次重新输入相同的锁。因此名称可重入(或递归)锁。