首页 > 解决方案 > loop.run_in_executor 函数是否需要 asyncio.lock() 或 threading.Lock()?

问题描述

我为我的项目复制了以下代码,它对我来说效果很好,但我真的不明白以下代码如何运行我的blocking_function:

@client.event
async def on_message(message):  
      loop = asyncio.get_event_loop()
      block_response = await loop.run_in_executor(ThreadPoolExecutor(), blocking_function)

每次收到消息时都会调用 on_message 。如果我收到多条消息,它们将被异步处理。

blocking_function 是一个同步函数,我不想在另一个blocking_function 运行时运行它。那么在blocking_function 中,我应该使用threading.Lock() 还是asyncio.lock()?

标签: python-3.xmultithreadingasynchronousparallel-processingpython-asyncio

解决方案


正如评论中 dirn 所指出的那样,blocking_function您不能使用 anasyncio.Lock因为它不是异步的。(相反的情况也适用:您不能threading.Lock从异步函数中锁定 a ,因为尝试这样做会阻塞事件循环。)如果您需要保护由 的其他实例访问的数据blocking_function,您应该使用 a threading.Lock

但我真的不明白下面的代码是如何运行我的blocking_function

它移交blocking_function给您创建的线程池来运行它。线程池排队并运行函数(从您的角度来看,这发生在“后台”),并run_in_executor安排事件循环在函数完成时得到通知,并将其返回值作为await表达式的结果传递。

请注意,您应该将None其用作 的第一个参数run_in_executor。如果使用ThreadPoolExecutor(),则为每条消息创建一个全新的线程池,并且永远不会丢弃它。线程池通常意味着创建一次,并为后续工作重用固定数量(“池”)的线程。None告诉 asyncio 使用它为此目的创建的线程池。


推荐阅读