何时获取块状态设置为 False 的锁?



我想知道为什么设置block=false是有意义的?

from multiprocessing import Process, Lock
lock.acquire(block=False)

如果我不需要阻止,我根本不会使用锁定?

Python in a Nutshell

L.acquire()
When 阻塞 为真,获取锁 L .如果 L 已锁定,调用线程挂起并等待 L 已解锁, 然后锁定 L .即使调用线程是上次锁定的线程 L ,它仍然挂起并等待另一个线程 释放 L .什么时候 阻塞 是假的和 L 已解锁,获取锁 L 并返回 True。什么时候 阻塞 是假的和 L 是 锁定,获取不影响 L ,并返回 False。

以及使用以下简单代码的实际示例:

from multiprocessing import Process, Lock, current_process

def blocking_testing(lock):
if not lock.acquire(False):
print('{} Couldn't get lock'.format(current_process().ident))
else:
print('{} Got lock'.format(current_process().ident))

if __name__ == '__main__':
lock = Lock()
for i in range(3):
procs = []
p = Process(target=blocking_testing, args=(lock,))
procs.append(p)
p.start()
for p in procs:
p.join()

使用上述版本(blocking=False)输出

12206 得到锁 12207 无法得到锁

12208 无法得到锁

如果我设置blocking=True(或删除它,因为它默认为True),主进程将挂起,因为Lock没有被释放。 最后,如果我设置blocking=True并在最后添加一个lock.release(),我的输出将是

12616 有锁 12617 有锁

12618 有锁

我希望这是一个足够清楚的解释。

multiprocessing.Lock不用于阻止,它用于保护一个或多个资源免受并发访问。

最简单的示例可能是由多个进程写入的文件。要保证一次只有一个进程在给定文件上写入,请使用Lock保护它。

在某些情况下,您的逻辑无法阻止。例如,如果逻辑由asyncio模块等事件循环编排,则阻塞将停止整个执行,直到释放Lock

在这种情况下,常见的方法是尝试获取Lock。如果成功,则继续访问受保护的资源,否则将移至其他例程并稍后再试。

这是有意义的,因为它的参数名称:blockblock=False提供非阻塞功能来访问受保护的资源。

示例一:

您有一个 GUI 线程和一个后台工作线程。您的 GUI 线程需要修改工作线程生成的一些数据,但您的 GUI 线程无法阻塞,因为它会阻塞整个交互。因此,您可以使用lock.acquire(block=False)安全地检查数据是否已准备就绪,而不会阻塞。

示例二:

另一个与事件循环相关的例子是asyncio,它提供了对受保护资源的无阻塞访问。

相关内容

  • 没有找到相关文章

最新更新