假设我有一个带有异步事件循环的线程和其他正在运行的线程。
例如,我可能必须使用锁机制来处理线程之间的同步。但是锁可能会阻塞协程...并且没有其他任务(在异步线程中)会同时运行。
解决办法是什么?我的猜测是,一种异步的锁原语可以完成这项工作,但据我所知,它并不存在。
准确地说:我不是指现有的异步锁原语。
使用 loop.run_in_executor 在线程中运行同步调用:
def synchronous_function():
with synchronous_lock:
# Do something
async def asynchronous_function():
await loop.run_in_executor(None, synchronous_function)
现在存在异步感知锁。您可以使用
aiologic.PLock
作为相应包提供的最快同步原语(我是 aiologic 的创建者)。它类似于threading.Lock
,并且它永远不会阻塞事件循环:
import asyncio
from threading import Timer
import aiologic
lock = aiologic.PLock()
async def a():
print("before enter")
async with lock:
pass
print("after exit")
async def b():
print("another task")
async def main():
async with asyncio.TaskGroup() as tasks:
lock.green_acquire()
tasks.create_task(a())
tasks.create_task(b())
Timer(1, lock.green_release).start()
asyncio.run(main()) # will take 1 second
但与
threading.Lock
不同,它省略了对冗余 release()
调用的检查。如果您需要它们,可以使用 aiologic.BoundedSemaphore
代替。