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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 01:53:13  来源:igfitidea点击:

What is the difference between Lock and RLock

pythonmultithreadinglockingreentrancy

提问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 Rlockand Lock?

我不确定为什么我们需要这个?什么之间的区别RlockLock

采纳答案by shx2

The main difference is that a Lockcan 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 RLockon 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 Lockcan be released by any thread, while an acquired RLockcan only be released by the thread which acquired it.

另一个区别是acquireLock可以被任何线程释放,而acquireRLock只能被获取它的线程释放。



Here's an example demostrating why RLockis 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 hare public(i.e. can be called directly by an external caller), and all of them require syncronization.

比方说,所有的fgh公共(即可以直接由外部调用程序调用),所有这些都需要同步化。

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 fcannot call gafter 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 RLockelegantly 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 RLockis 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 RLockinstead, however, the recursive calls can reenter the same lock as many times as needed. Hence the name reentrant(or recursive) lock.

由于递归调用,该函数会导致死锁。RLock但是,如果我们改为使用,递归调用可以根据需要多次重新输入相同的锁。因此名称可重入(或递归)锁。