异步生产者/消费者串行运行

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

我正在开始使用

asyncio
并创建了这个:

import asyncio

async def handle_data(q):
    while (item := await q.get()) is not None:
        print(f'Consuming {item}')

async def main():
    q = asyncio.Queue()
    consumer = asyncio.create_task(handle_data(q))

    for k in range(10):
        print(f'Producing {k}')
        await q.put(k)

    await q.put(None)
    await consumer

asyncio.run(main())

脚本输出

Producing 0
Producing 1
Producing 2
Producing 3
Producing 4
Producing 5
Producing 6
Producing 7
Producing 8
Producing 9
Consuming 0
Consuming 1
Consuming 2
Consuming 3
Consuming 4
Consuming 5
Consuming 6
Consuming 7
Consuming 8
Consuming 9

为什么代码会同步运行?

python python-asyncio
1个回答
0
投票

在您的代码中,会发生同步行为,因为

handle_data
协程仅在
main
生成所有项目之后启动一次。要使生产者和消费者同时运行,您需要同时启动这两个任务。 调整方法如下:

  1. 开始生产物品之前
    启动handle_data作为后台任务。

  2. 使用

    await asyncio.gather()
    同时运行生产者和消费者。

这是修改后的代码:

import asyncio

async def handle_data(q):
    while (item := await q.get()) is not None:
        print(f'Consuming {item}')

async def produce_data(q):
    for k in range(10):
        print(f'Producing {k}')
        await q.put(k)
    await q.put(None)

async def main():
    q = asyncio.Queue()
    consumer = asyncio.create_task(handle_data(q))
    producer = asyncio.create_task(produce_data(q))

    await asyncio.gather(producer, consumer)

asyncio.run(main())

说明

  • 现在,

    produce_data
    生产物品,而
    handle_data
    并行消耗它们,两者通过
    asyncio.gather()
    同时运行。

  • 每当生产者将一个项目添加到队列中时,消费者就可以立即消费它,从而产生交错的“生产”和“消费”输出。

我希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.