gpt4 book ai didi

python - asyncio.Condition 中的锁除了兼容 threading.Condition 之外还有其他用途吗?

转载 作者:太空宇宙 更新时间:2023-11-03 14:43:21 31 4
gpt4 key购买 nike

我想问一下asyncio.Condition .我对这个概念并不熟悉,但我从学生时代就知道并了解锁、信号量和队列。

我找不到很好的解释或典型的用例,只是 this example .我看了看来源。核心功能是通过 future FIFO 实现的。每个等待协程都会添加一个新的 future 并等待它。另一个协程可能会调用 notify(),它会设置来自 FIFO 的一个或多个 futures 的结果,并唤醒相同数量的等待协程。到目前为止真的很简单。

然而,实现和使用比这更复杂。等待协程必须首先获取与条件关联的锁才能等待(并且 wait() 在等待时释放它)。通知者也必须获得一个锁才能通知()。这导致每个操作之前的 with 语句:

async with condition:
# condition operation (wait or notify)

否则会发生 RuntimeError

我不明白拥有这把锁的意义。我们需要用锁来保护什么资源?在 asyncio 中,事件循环中可能总是只有一个协程在执行,没有线程中已知的“关键部分”。

这个锁真的需要(为什么?)还是只是为了与线程代码兼容?

我的第一个想法是为了兼容性,但在这种情况下,为什么他们不在保留用法的同时移除锁呢?即制作

async with condition:

基本上是一个可选的空操作。

最佳答案

这个问题的答案与 threading.Condition vs threading.Event 基本相同。 ;没有锁的条件是事件,而不是条件(*)

条件用于表示资源可用。等待条件的任何人都可以使用该资源,直到他们用完为止。为确保没有其他人可以使用该资源,您需要锁定该资源:

resource = get_some_resource()

async with resource.condition:
await resource.condition.wait()
# this resource is mine, no-one will touch it
await resource.do_something_async()

# lock released, resource is available again for the next user

请注意在 wait() 恢复后锁是如何没有释放的!在锁被释放之前,没有其他等待相同条件的协程可以继续,对资源的访问是通过锁进行独占的。请注意,锁在等待时被释放,因此其他协程可以将自己添加到队列中,但要使 wait() 最终返回锁,必须先重新获取锁。

如果您不需要协调对共享资源的访问,请使用事件;条件基本上是将锁和事件组合成一个原语,避免了常见的实现陷阱。

请注意,多个条件可以共享锁。这会让您发出特定阶段的信号,其他协程可以等待该特定阶段到达。共享锁将协调对单个资源的访问,但在启动每个阶段时会发出不同的条件信号。

对于线程,所提供条件的典型用例是单个生产者和多个消费者都在等待生产者处理的项目。工作队列是共享资源,生产者获取条件锁将一个项目压入队列,然后调用notify(),此时等待条件的下一个消费者获得锁(因为它从 wait()) 返回并且可以从队列中移除要处理的项目。这并不能完全转化为基于协程的应用程序,因为协程没有线程系统所具有的坐着闲置等待工作完成的问题,它更容易启动消费者协程根据需要执行例程(可能使用信号量来设置上限)。

也许更好的例子是 aioimaplib library ,它完全支持 IMAP4 交易。这些事务是异步的,但您需要有权访问共享连接资源。因此,该库使用单个 Condition 对象和 wait_for() 来等待特定状态的到来,从而为等待该事务状态的协程提供独占连接访问权限。


(*):事件与条件有不同的用例,因此与没有锁定的条件的行为略有不同。一旦设置,事件需要明确清除,而条件在使用时“自动清除”,并且在没有人等待条件时永远不会“设置”。但是,如果您想在任务之间发出信号并且不需要控制对共享资源的访问,那么您可能需要一个事件。

关于python - asyncio.Condition 中的锁除了兼容 threading.Condition 之外还有其他用途吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51516666/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com