为何基于asyncio的异步生产者/消费者程序串行运行?
为什么这段异步生产者/消费者代码会串行运行?
核心原因是asyncio的任务切换仅在协程遇到可挂起的await操作时才会发生,而你的代码里生产者的await q.put(k)并没有触发挂起,导致生产者一口气跑完所有生产逻辑,之后消费者才开始执行。
具体细节:
- asyncio.Queue默认是无界队列,
q.put()只有在队列达到设定的最大容量时才会挂起当前协程。你的代码没设置队列大小,所以每次await q.put(k)都会立刻完成,不会让出CPU给消费者任务。 - 生产者的循环里,除了
await q.put(k)没有其他会触发任务切换的操作,所以生产者会连续执行完10次"Producing"打印和入队操作,直到整个循环结束。 - 只有当生产者执行完所有入队操作、开始等待消费者任务时,事件循环才会切换到消费者任务,一次性处理队列里的所有元素。
如果想让生产和消费交替进行,可以给队列设置一个较小的容量,比如maxsize=1,这样当队列满时,q.put()会挂起生产者,事件循环就会切换到消费者处理元素,示例代码如下:
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(maxsize=1) # 设置队列最大容量为1 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 Consuming 0 Producing 1 Consuming 1 Producing 2 Consuming 2 ...
内容的提问来源于stack exchange,提问作者August Vrubel
相关产品推荐
相关产品推荐

