![](/img/trans.png)
[英]How to know if a Python multiprocessing.Lock is released or not?
[英]python how to know if current thread is holding a lock
我有一个threading.Lock
object 我想知道current_thread
是否持有这个锁。 实现这一目标的最简单方法是什么?
没有直接的方法可以通过我知道的threading.Lock
对象执行此操作。 那些确实具有locked
属性,但是在所有线程中都会显示为True
,而不仅仅是拥有的线程。 RLock
是可能的,但是您必须访问RLock对象上的内部__owner
属性,建议不要这样做,也不能保证它总是可以工作。 要做的代码看起来像这样,它的价值:
#!/usr/bin/python
import threading
import time
def worker():
if l._RLock__owner is threading.current_thread():
print "I own the lock"
else:
print "I don't own the lock"
l.acquire()
if l._RLock__owner is threading.current_thread():
print "Now I own the lock"
else:
print "Now I don't own the lock"
time.sleep(5)
l.release()
if __name__ == "__main__":
l = threading.RLock()
thds = []
for i in range(0, 2):
thds.append(threading.Thread(target=worker))
thds[i].start()
for t in thds:
t.join()
这是输出:
dan@dantop:~> ./test.py
I don't own the lock
Now I own the lock
I don't own the lock
但实际上,您的代码实际上不需要这样做。 为什么您感觉需要此显式检查? 通常,在编写代码块时,您会知道在该上下文中是否已获取锁。 您能否分享一个您认为需要检查的示例?
release
方法的帮助文本:
Help on built-in function release:
release(...)
release()
Release the lock, allowing another thread that is blocked waiting for
the lock to acquire the lock. The lock must be in the locked state,
but it needn't be locked by the same thread that unlocks it.
这意味着Lock
对象并不关心谁锁定了它们,因为任何线程都可以解锁它们。 因此,对于未修改的锁对象,由于没有线程“持有”该锁,因此无法确定当前线程是否是持有该锁的线程-它只是被锁定还是已解锁。
我假设您想知道您是否持有该锁的原因是,这样您就不会在已经拥有锁的情况下尝试获取它。 例如:
def a():
with theLock:
do_stuff()
b()
do_other_stuff()
def b():
with theLock:
do_b_stuff()
在这里,如果线程还没有锁,则theLock
在b()
获取Lock。 正如我在评论中提到的,这是可重入锁的完美用例。 如果您这样创建锁:
theLock = threading.RLock()
然后,我展示的示例就可以正常工作-当您调用a()
,它将获得锁。 然后在b()
,它使您无需抱怨即可重新获取该锁。 另外,如果您使用上下文管理器语法( with theLock:
,则无需担心一个警告。
需要注意的是,如果您手动调用acquire
和release
,则需要确保每次调用acquire
时都调用一次release
。 在上面的示例中,如果我在a()
和b()
theLock.acquire()
中都调用了theLock.acquire()
,那么我也需要在两个函数中都调用release()
。 如果您调用两次acquire
并且仅release
一次,则该线程仍将保留该锁,从而使其他线程无法获取该锁。
请看一下线程同步机制
您可以尝试以下
import threading
lock = threading.Lock()
lock.acquire()
#now that the lock is taken, using lock.acquire(False) will return False
if not lock.acquire(False):
# could not lock the resource
现在添加一个扭曲:
import threading
class customLock(object):
_accessLock = threading.Lock()
def __init__(self):
self._lock = threading.Lock()
self.ownerThread = None
def acquire(self, thread):
self._accessLock.acquire()
try:
if self._lock.acquire():
self.ownerThread = thread
finally:
self._accessLock.release()
def release(self):
self._accessLock.acquire()
try:
self._lock.release()
self.ownerThread = None
finally:
self._accessLock.release()
def getOwner(self):
return self.ownerThread
def acquire(self, blocking=True):
return self._lock.acquire(blocking)
将初始示例转换为:
import threading
lock = customLock()
lock.acquire(threading.current_thread())
#now that the lock is taken, using lock.acquire(False) will return False
if not lock.acquire(False):
# could not lock the resource
if lock.getOwner() is threading.current_thread():
# do something
希望这可以帮助
在Python 3.9.5,获取一个RLock
object的owner线程:
出于调试目的:您可以简单地打印锁定,output 就像
<unlocked _thread.RLock object owner=0 count=0 at 0x7f77467d1030>
查看owner
属性,其中包含所有者线程的线程 ID。
以编程方式获取所有者的值:(警告:使用实现细节,可能会在未来的版本中中断;另请注意,在检查所有者和实际使用信息之间可能存在竞争条件)
这取决于 Python 是使用 Python 实现还是 C 实现。
In [12]: threading._CRLock() # this is a recursive lock implemented in C Out[12]: <unlocked _thread.RLock object owner=0 count=0 at 0x7f7746878cc0> In [13]: threading._PyRLock() # this is a recursive lock implemented in Python Out[13]: <unlocked threading._RLock object owner=None count=0 at 0x7f7746764cd0>
以下方法仅在实现在 Python 中时有效。
只需访问_owner
属性:
threading._PyRLock()._owner
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.