asyncio.Queue conecta productores y consumidores dentro de un event loop. Con maxsize, un productor rápido espera cuando el backlog alcanza el límite, evitando crecimiento descontrolado de memoria.
import asyncio
async def consumidor(fila: asyncio.Queue[int | None]) -> None:
while (item := await fila.get()) is not None:
try:
await asyncio.sleep(0.05)
print(item)
finally:
fila.task_done()
fila.task_done()
async def main() -> None:
fila: asyncio.Queue[int | None] = asyncio.Queue(maxsize=10)
worker = asyncio.create_task(consumidor(fila))
for item in range(5):
await fila.put(item)
await fila.put(None)
await fila.join()
await worker
asyncio.run(main())
Cada elemento retirado con get() necesita task_done(). El centinela también cuenta y debe marcarse. join() no detiene consumidores; solo espera a que el trabajo pendiente llegue a cero.
Buenas prácticas
Usa await con put() y get() para respetar el backpressure. Los métodos no reciben timeout directamente, así que envuelve la operación con la herramienta adecuada de tu versión. Define políticas para fallos, cancelación y reintentos.
Usa asyncio.TaskGroup para supervisar consumidores. Si los productores están en threads, elige queue.Queue.
La documentación oficial de asyncio.Queue, consultada el 22 de julio de 2026, detalla la API y sus límites.