首页 > 解决方案 > 在异步方法开始之前获取锁

问题描述

假设我有一个multiprocessing.Lock实例(lock如下),我想在协程实际开始运行之前获取foo它(比如说它是由一些未来的 I/O 或信号触发的,所以我不想在整个期间持有锁它被阻塞了,而只是在它运行时。)有没有办法在不修改foo自身主体的情况下做到这一点?为了显示:

无锁:

await foo()

带锁:

lock.acquire()
await foo()
lock.release()

foo据我所知,将其包装在另一个函数中无济于事,async因为它仍然需要以await相同的方式进行编辑。直接处理也无济于事asyncio.Future,因为我所能做的就是add_done_callback. 或者任何其他“链接”回调的概念与将其包装在一个async函数中相同——如果我将获取锁的未来放在未来之前foo,它将立即有效地运行,并且锁将在整个持续时间内被持有,直到foo实际开始。

是改变身体foo的唯一方式还是有我没有看到的解决方法?


更具体地说,以防万一,我的情况实际上foo是实例的get方法。asyncio.Queue因此,用两行方法子类化并覆盖这个单行方法可能就足够了,它首先完成我想要的锁获取。或者monkeypatch实例上的方法。但这似乎进入了丑陋的领域。

https://github.com/python/cpython/blob/1e1dbdf23f7a18f53a3257badc3541973831f2c4/Lib/asyncio/queues.py#L57-L58

标签: pythonmultithreadingpython-asyncio

解决方案


评论后更新。

一般来说,在使用锁时,您应该尽可能短地持有它们。

如果您需要使用锁,则编写子类可能是要走的路。

您的问题没有包含足够的细节来提供其他明智的建议。


推荐阅读