获取阻塞锁是否被阻塞
Get whether a blocking lock blocked
在Python 3,我想获取一个锁,然后知道是否阻塞。问题是 threading.Lock.acquire
总是 return s True
如果用 blocking=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
就会发生变化。该函数应该 return 调用时正在计算的 foo
的值。如果 foo
发生变化,则它不能再 return 该值。
理想情况下,我们会有一个 acquire
函数可以阻塞并且仍然 return 无论它是否被阻塞。这样,我们可以自信地断言函数总是 returns 是调用函数时正在计算的 foo
的值,并且只有当 foo
尚未被计算时才会函数然后继续计算它,然后 return 新值。这可以在 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
在Python 3,我想获取一个锁,然后知道是否阻塞。问题是 threading.Lock.acquire
总是 return s True
如果用 blocking=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
就会发生变化。该函数应该 return 调用时正在计算的 foo
的值。如果 foo
发生变化,则它不能再 return 该值。
理想情况下,我们会有一个 acquire
函数可以阻塞并且仍然 return 无论它是否被阻塞。这样,我们可以自信地断言函数总是 returns 是调用函数时正在计算的 foo
的值,并且只有当 foo
尚未被计算时才会函数然后继续计算它,然后 return 新值。这可以在 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