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
- Crea un timeout personalizado.
- Implementa un semáforo para limitar acceso.
- Crea un pipeline asíncrono con 3 pasos.
- Implementa cancelación en cascada.
- Usa wait para detectar tareas completadas.
# semáforo
sem = asyncio.Semaphore(2)
# cancelación en cascada
t.cancel(); await t
# pipeline
async def paso(x): await asyncio.sleep(1); return x*2
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())