簡體   English   中英

獲取阻塞鎖是否阻塞

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM