IOKELU
Nivel: Avanzado – Guía 7
💡 Prueba el código:
Ejecuta cualquier ejemplo en nuestra consola interactiva: Abrir consola de Python →

asyncio en profundidad: Event Loop, Tasks y Corutinas

asyncio es el módulo central de Python para programación asíncrona. Permite gestionar miles de tareas concurrentes con un solo hilo mediante un event loop. En esta guía aprenderás cómo funciona internamente, cómo crear tasks, cómo manejar cancelaciones, timeouts, sincronización y patrones avanzados usados en servidores, scrapers y sistemas de IO intensivo.

Tabla de contenidos

  • El event loop
  • Corutinas y tasks
  • asyncio.create_task
  • asyncio.gather vs asyncio.wait
  • Cancelación de tareas
  • Timeouts
  • Sincronización: Lock, Event, Semaphore
  • Ejercicios
  • Mini‑proyecto

1. El event loop

El event loop es el núcleo de asyncio: gestiona corutinas, IO, timers y tasks.

import asyncio

async def hola():
    print("Hola desde el loop")

loop = asyncio.get_event_loop()
loop.run_until_complete(hola())

2. Corutinas y tasks

async def trabajo():
    await asyncio.sleep(1)
    return "OK"

async def main():
    tarea = asyncio.create_task(trabajo())
    print(await tarea)

asyncio.run(main())

3. asyncio.create_task

async def tarea(n):
    await asyncio.sleep(1)
    print("Tarea", n)

async def main():
    tareas = [asyncio.create_task(tarea(i)) for i in range(5)]
    await asyncio.gather(*tareas)

asyncio.run(main())

4. asyncio.gather vs asyncio.wait

# gather espera todas las tareas y devuelve resultados
resultados = await asyncio.gather(t1, t2, t3)

# wait permite controlar completadas y pendientes
done, pending = await asyncio.wait([t1, t2, t3])

5. Cancelación de tareas

async def tarea():
    try:
        await asyncio.sleep(5)
    except asyncio.CancelledError:
        print("Cancelada")

async def main():
    t = asyncio.create_task(tarea())
    await asyncio.sleep(1)
    t.cancel()
    await t

asyncio.run(main())

6. Timeouts

async def lento():
    await asyncio.sleep(3)

async def main():
    try:
        await asyncio.wait_for(lento(), timeout=1)
    except asyncio.TimeoutError:
        print("Timeout")

asyncio.run(main())

7. Sincronización: Lock, Event, Semaphore

import asyncio

lock = asyncio.Lock()

async def critico(n):
    async with lock:
        print("Acceso:", n)
        await asyncio.sleep(1)

async def main():
    await asyncio.gather(critico(1), critico(2))

asyncio.run(main())

8. Ejercicios

9. Mini‑proyecto: Pool de workers asíncronos

import asyncio

async def worker(id, queue):
    while True:
        tarea = await queue.get()
        print(f"Worker {id} procesando {tarea}")
        await asyncio.sleep(1)
        queue.task_done()

async def main():
    queue = asyncio.Queue()

    workers = [asyncio.create_task(worker(i, queue)) for i in range(3)]

    for i in range(10):
        await queue.put(f"Tarea {i}")

    await queue.join()

    for w in workers:
        w.cancel()

asyncio.run(main())

Siguiente guía

Concurrencia con threading →