¿Qué es la programación asíncrona en Python?
La programación asíncrona es una forma de escribir código donde las tareas no se ejecutan de manera secuencial, sino en paralelo o a la espera de eventos sin bloquear el hilo principal de ejecución. En el desarrollo moderno, el uso eficiente de los recursos y el tiempo de ejecución de las aplicaciones juega un papel clave.
La programación asíncrona permite:
- Acelerar la ejecución de tareas
- Mejorar la capacidad de respuesta de los programas
- Utilizar los recursos del sistema de forma racional
Principales ventajas de la asincronía
Áreas de aplicación
La programación asíncrona es especialmente útil para operaciones de entrada/salida:
- Trabajo con archivos
- Peticiones de red (API HTTP)
- Interacción con bases de datos
- Manejo de WebSockets
- Procesamiento de grandes volúmenes de datos
Diferencias con el multihilo
A diferencia del multihilo, la asincronía no requiere crear hilos o procesos adicionales. Esto reduce la carga del sistema y evita problemas de bloqueos y sincronización de datos entre hilos.
¿Cómo funciona la asincronía en Python?
Python ofrece soporte integrado para la programación asíncrona a través del módulo asyncio, que se añadió oficialmente a la biblioteca estándar a partir de la versión 3.4.
Conceptos clave
async def— define una función asíncrona (corrutina)await— indica que se debe esperar la ejecución de una corrutinaasyncio— módulo estándar para trabajar con tareas asíncronasevent loop— bucle de eventos que gestiona la ejecución de las corrutinas
Ejemplo básico de una función asíncrona
import asyncio
async def saludar():
print("¡Hola!")
await asyncio.sleep(1)
print("Pasó 1 segundo")
asyncio.run(saludar())
En este ejemplo, await asyncio.sleep(1) simula la espera de una operación que consume recursos, como una petición de red.
Creación y uso de funciones asíncronas
Definir una función asíncrona
Para crear una función asíncrona, usa la palabra clave async antes de la definición de la función:
async def obtener_datos():
print("Solicitando datos...")
await asyncio.sleep(2)
print("Datos recibidos")
Llamar a una función asíncrona
La llamada a una función asíncrona se realiza mediante asyncio.run():
asyncio.run(obtener_datos())
Ejecución paralela de múltiples tareas
Uso de asyncio.gather()
Para ejecutar varias corrutinas en paralelo, usa asyncio.gather():
async def tarea(nombre, retardo):
print(f"Inicio de la tarea {nombre}")
await asyncio.sleep(retardo)
print(f"Tarea {nombre} completada")
async def main():
await asyncio.gather(
tarea("A", 2),
tarea("B", 1),
tarea("C", 3)
)
asyncio.run(main())
Formas alternativas de lanzar tareas
Además de asyncio.gather(), se puede usar:
asyncio.create_task()— para crear tareas individualesasyncio.wait()— para esperar la finalización de tareas con opciones adicionalesasyncio.as_completed()— para obtener resultados a medida que estén listos
Iteradores y generadores asíncronos
Creación de un iterador asíncrono
Para procesar flujos de datos de forma asíncrona, usa iteradores asíncronos:
class ContadorAsync:
def __init__(self, max_count):
self.max_count = max_count
s