我有一个threading.Lock
对象,我想知道current_thread
是否持有此锁。实现这一目标的最简单方法是什么?
答案 0 :(得分:6)
对于我所知道的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
但实际上,你的代码真的不应该这样做。为什么你觉得你需要这个明确的检查?通常,当您编写代码块时,您将知道是否已在该上下文中获取锁定。你能分享一个你认为需要检查它的例子吗?
答案 1 :(得分:1)
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()
。正如我在评论中提到的,这是一个重入锁的完美用例。如果您创建这样的锁:
theLock = threading.RLock()
然后我提供的示例工作正常 - 当您调用a()
时,它获取锁定。然后在b()
中,它允许您重新获取锁定而不会抱怨。此外,如果您使用上下文管理器语法(with theLock:
),您将不必担心一个警告。
需要注意的是,如果您手动拨打acquire
和release
,则需要确保每次拨打release
时都拨打acquire
一次。在上面的示例中,如果我在theLock.acquire()
和a()
中都调用了b()
,那么我也需要在这两个函数中调用release()
。如果你只调用acquire
两次而release
只调用一次,那么该线程仍将保持锁定,使其他线程无法获取锁定。
答案 2 :(得分:0)
请查看Thread Synchronization Mechanisms
您可以尝试以下
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
希望这有帮助