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