![](/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.