如何在主异步循环内的同步子进程内运行多个异步循环?

Posted

技术标签:

【中文标题】如何在主异步循环内的同步子进程内运行多个异步循环?【英文标题】:How to run multiple asyncio loops inside syncrhonous sub-processes inside a main asyncio loop? 【发布时间】:2021-12-12 04:53:17 【问题描述】:

我有一个使用asyncio 运行的主函数,然后在其中使用event_loop.run_in_executor() 运行阻塞函数的多个进程。

我希望在每个进程中为每个进程运行一个新的 asyncio 循环,以便执行异步代码。

所以我有一个主要的异步函数,我在其中创建多个进程,并且我想在每个进程中创建一个新的异步循环。如何做到这一点?

【问题讨论】:

【参考方案1】:

你可以在你的子进程中调用asyncio.run,使用一个协程来完成你想要做的异步工作。一个启动 5 个进程的最小示例,每个进程都有自己的事件循环:

import asyncio
from concurrent.futures import ProcessPoolExecutor


def run_loop_in_process():
    async def subprocess_async_work():
        await asyncio.sleep(5) #whatever async code you need
    asyncio.run(subprocess_async_work())

async def main():
    loop = asyncio.get_running_loop()
    pool = ProcessPoolExecutor()
    tasks = [loop.run_in_executor(pool, run_loop_in_process) for _ in range(5)]
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

【讨论】:

所以你可以在 asyncio.run() 中调用 asyncio.run() 吗? @KZiovas 是的,因为你在一个单独的子进程中调用它,你会得到一个新的事件循环,所以它是安全的。请记住,同一进程中的两个事件循环会导致问题。 我测试它确实有效,我必须更改的一件事是各种对象self.variable,我在我想在子流程中运行的函数中重用它。我不得不在每个子流程中重新声明变量,因为它们试图使用相同的资源(一些客户端对象)。但这是意料之中的。

以上是关于如何在主异步循环内的同步子进程内运行多个异步循环?的主要内容,如果未能解决你的问题,请参考以下文章

异步循环内的异步循环

如何在库函数中使用异步事件循环

如何在节点 js 中正确使用等待/异步与 for 循环

异步方法运行速度太快,无法在主线程上更新我的列表框 [重复]

当脚本在多处理工作人员中运行异步事件循环时,通过子进程运行脚本会挂起

在 KeyboardInterrupt 上关闭异步循环 - 运行停止例程