![](/img/trans.png)
[英]Python: Is there a thread safe way to know if lock.acquire() has blocked (and continue blocking)?
[英]Get whether a blocking lock blocked
在 Python 3 中,我想獲取一個鎖,然后知道它是否被阻塞。 問題是threading.Lock.acquire
如果使用blocking=True
調用它總是返回True
,所以沒有辦法判斷在調用函數時鎖是否已經被鎖定。 以這段代碼為例:
import threading
foo = None
lock = threading.Lock()
def bar():
global foo
# Only compute foo in one thread at a time.
if not lock.acquire(blocking=False):
# The race condition exists here.
# Another thread is already computing foo.
# This instance does not need to recompute foo.
# Wait for that instance to finish.
with lock:
# Just return the value that the other instance computed.
return foo
# No other instance of this function is computing foo.
with lock:
# Compute foo.
foo = [something]
return foo
這里的問題是,當上面代碼中的注釋指出存在競爭條件時,可以再次獲取lock
。
如果這是因為第三個線程在函數中的同一點上首先繼續並獲得了鎖,這是不可取的,因為它引入了輕微的延遲。 真的沒有理由需要保護return foo
; 兩個線程應該能夠同時完成。
但是,如果獲取是由於另一個線程重新計算foo
,那么這是不可取的,因為一旦釋放鎖, foo
就會改變。 該函數應返回調用時正在計算的foo
的值。 如果foo
改變了,那么它就不能再返回那個值了。
理想情況下,我們會有一個acquire
函數,它可以阻塞並且無論是否阻塞仍然返回。 這樣,我們可以自信地斷言該函數總是返回調用函數時正在計算的foo
的值,並且只有當foo
尚未被計算時,該函數才會繼續計算它,並返回新值. 這可以在 Python 中完成嗎?
我知道這個問題很老,但由於我在尋找其他東西時偶然發現了它並且沒有答案,我想我會做任何找到它的服務並回答它的人。
您通過首先檢查鎖是否可用來導致競爭條件。 您應該嘗試在不檢查的情況下獲取鎖,如下所示:
import threading
foo = None
lock = threading.Lock()
def bar():
global foo
# Only compute foo in one thread at a time.
with lock:
# Only compute foo once.
if foo is None:
foo = [something]
# Just return the value that is now guaranteed to be computed.
return foo
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.