python异步生成器误解

问题描述 投票:0回答:1

我对

asyncio
很陌生,尤其是 Python 中的异步生成器。 这是我不理解其行为的基本代码。它是关于模拟等待的睡眠,即从远程数据库产生的值的“get()”:

import asyncio

async def async_gen():
    for i in range(5):
        print(f"entering iteration {i}")
        await asyncio.sleep(3)
        print(f"ending iteration {i}")
        yield i

async def main():
    async for value in async_gen():
        print(value)

asyncio.run(main())

我期待:

  • 迭代
    i
    打印
    entering iteration i
  • 然后等待 3 秒休眠并立即进入下一次迭代
    i+1
    并打印
    entering iteration i+1

换句话说,我期望所有

entering
打印都是立即的,3 秒后,所有
ending
打印都是立即的。总运行时间应为 3 秒:

entering iteration 0
entering iteration 1
entering iteration 2
entering iteration 3
entering iteration 4
ending iteration 0
0
ending iteration 1
1
ending iteration 2
2
ending iteration 3
3
ending iteration 4
4

相反,执行会提供以下内容,每个

entering iteration i
/
ending iteration i
之间有 3 秒,总时间为 5*3 秒 = 15 秒:

entering iteration 0
ending iteration 0
0
entering iteration 1
ending iteration 1
1
entering iteration 2
ending iteration 2
2
entering iteration 3
ending iteration 3
3
entering iteration 4
ending iteration 4
4

我确信我有些地方不太好。

欢迎任何帮助。

非常感谢

问候

python asynchronous python-asyncio
1个回答
0
投票

在您的情况下, main() 是单个任务。如果你想要并发,你必须为每次迭代创建单独的任务。

例如:

import asyncio


async def some_func(i: int):
    print(f"entering iteration {i}")
    await asyncio.sleep(3)
    print(f"ending iteration {i}")


async def async_gen():
    for i in range(5):
        yield i


async def main():
    tasks = []

    async for value in async_gen():
        # launching concurrent task
        task = asyncio.create_task(some_func(value))
        tasks.append(task)

    # wait for all tasks to finish
    await asyncio.gather(*tasks)


asyncio.run(main())
© www.soinside.com 2019 - 2024. All rights reserved.