簡體   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