繁体   English   中英

python 如何知道当前线程是否持有锁

[英]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()

在这里,如果线程还没有锁,则theLockb()获取Lock。 正如我在评论中提到的,这是可重入锁的完美用例。 如果您这样创建锁:

theLock = threading.RLock()

然后,我展示的示例就可以正常工作-当您调用a() ,它将获得锁。 然后在b() ,它使您无需抱怨即可重新获取该锁。 另外,如果您使用上下文管理器语法( with theLock: ,则无需担心一个警告。

需要注意的是,如果您手动调用acquirerelease ,则需要确保每次调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM