繁体   English   中英

如何在 Python 中同时迭代和运行 AsyncGenerator

[英]How to iterate and run AsyncGenerator concurrently in Python

对 Python 有点陌生,不知道这个问题是不是太天真了。 试图掌握并发模型。

第三方函数(来自库)通过 ssh 连接到多个主机并执行一些 bash 命令。 此函数返回 AsyncGenerator。

然后我的代码使用async for遍历这个 AsyncGenerator:

        # some code before
        asyncgenerator_var = # ...
        async for (host, exit_code, stdout, stderr) in asyncgenerator_var:
            if exit_code != 0:
                self.err(f"[{host}]: {''.join(decode_strings(stderr))}")
                continue
            self.out(f"[{host}]: {''.join(decode_strings(stdout))}")
            self.err(f"[{host}]: {''.join(decode_strings(stderr))}")
        # some code after

然后代码调用 await 这个函数。 但是如果一个接一个地运行。 不是同时的。

代码有人解释为什么会这样? 以及应该做些什么来使它同时运行。

在异步模型中,没有函数同时运行。 如果当前函数正在await其他函数/未来,则事件循环可能会切换函数。

async for语句本质上意味着事件循环可以在迭代之间运行其他计划的回调/任务。

主体的async for仍然按照异步生成器产生的顺序运行。

要以任意顺序运行主体,请将其包装在异步函数中。 为每个输入创建一个单独的任务,最后gather所有任务的结果。

# some code before

asyncgenerator_var =  # ...

async def task(host, exit_code, stdout, stderr):
    if exit_code != 0:
        self.err(f"[{host}]: {''.join(decode_strings(stderr))}")
        return 
    self.out(f"[{host}]: {''.join(decode_strings(stdout))}")
    self.err(f"[{host}]: {''.join(decode_strings(stderr))}")
    
tasks = []
async for (host, exit_code, stdout, stderr) in asyncgenerator_var:
    tasks.append(asyncio.create_task(task, host, exit_code, stdout, stderr))

await asyncio.gather(*tasks)
    
# some code after

暂无
暂无

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

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