繁体   English   中英

如何正确使用 concurrent.futures 和 asyncio

[英]How to properly use concurrent.futures with asyncio

我正在制作一个 FastAPI 应用程序原型,它的端点将使用 subprocess 模块启动长时间运行的进程。 显而易见的解决方案是使用 concurrent.futures 和 ProcessPoolExecutor,但是我无法获得我想要的行为。 代码示例:

import asyncio
from concurrent.futures import ProcessPoolExecutor
import subprocess as sb
import time
import random

pool = ProcessPoolExecutor(5)

def long_task(s):
    print("started")
    time.sleep(random.randrange(5, 15))
    sb.check_output(["touch", str(s)])
    print("done")

async def async_task():
    loop = asyncio.get_event_loop()
    print("started")
    tasks = [loop.run_in_executor(pool, long_task, i) for i in range(10)]
    while True:
        print("in async task")
        done, _ = await asyncio.wait(tasks, timeout=1)
        for task in done:
            await task
        await asyncio.sleep(1)


def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(async_task())


if __name__ == "__main__":
    main()

从表面上看,这个示例工作正常,但生成的进程在执行完成后不会停止 - 我在ps aux | grep python中看到所有 python 进程 ps aux | grep python 不应该等待完成的任务停止它吗? 最后,我不太关心执行的结果,它应该在后台发生并干净地退出 - 没有任何挂起的进程。

使用完 ProcessPool 后,必须通过显式调用它的shutdown()方法或在 ContextManager 中使用它来关闭它。 我使用了 ContextManager 方法。

我不知道 subprocess.check_output 是做什么的,所以我把它注释掉了。

我还用对 asyncio.gather 的一次调用替换了你的无限循环,这将在 Executor 完成之前产生。

我在 Windows 上,所以为了观察进程的创建/删除,我查看了 Windows 任务管理器。 程序创建 5 个子进程,并在 ProcessPool 上下文管理器退出时再次关闭它们。

import asyncio
from concurrent.futures import ProcessPoolExecutor
# import subprocess as sb
import time
import random

def long_task(s):
    print("started")
    time.sleep(random.randrange(5, 15))
    # sb.check_output(["touch", str(s)])
    print("done", s)

async def async_task():
    loop = asyncio.get_event_loop()
    print("started")
    with ProcessPoolExecutor(5) as pool:
        tasks = [loop.run_in_executor(pool, long_task, i) for i in range(10)]
        await asyncio.gather(*tasks)
    print("Completely done")

def main():
    asyncio.run(async_task())

if __name__ == "__main__":
    main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM