繁体   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