Asíncrono para bucle en Python

Abdul Mateen 10 octubre 2023
  1. Función asíncrona en Python
  2. Bucle for asíncrono en Python
Asíncrono para bucle en Python

Este tutorial proporcionará detalles completos sobre los bucles for asíncronos en Python. Discutiremos la función asíncrona, el bucle for asíncrono y los conceptos de sleep.

A continuación, analizaremos la biblioteca de Python asyncio y las funciones necesarias para ejecutar código asíncrono. Finalmente, veremos un par de ejemplos en Python para entender completamente el concepto.

Función asíncrona en Python

Las funciones asíncronas ayudan a ejecutar tareas pesadas (como programas por lotes, tal vez nos interese ejecutar procesos en segundo plano) en paralelo a otras funciones del mismo programa. Es posible ejecutar funciones en paralelo cuando las funciones no dependen entre sí o no dependen completamente entre sí.

Una función síncrona devuelve el control una vez que se completa la tarea, mientras que una función asíncrona devuelve el control para ejecutar otras funciones/código en paralelo y recupera el control después de un tiempo. De esta manera, no solo se completa la tarea pesada, sino que también se completan muchas otras tareas en paralelo.

Técnicamente, una función síncrona bloquea el control de la función main, mientras que una función asíncrona se ejecuta sin bloquear la función main. De esta forma, la función main puede ejecutar múltiples funciones asíncronas en paralelo.

Bucle for asíncrono en Python

Para los bucles síncronos, se ejecutan sin pausa ni control; sin embargo, para hacerlos asíncronos, tenemos que definirlos en alguna función asíncrona. Además, necesitamos dormir en este proceso durante un tiempo para dar control a alguna otra función.

Utilice la declaración sleep

Un proceso/subproceso/función puede quedarse dormido durante algún tiempo; puedes considerarlo un descanso. Sin embargo, el propósito es perder el control durante algún tiempo.

Como resultado, alguna otra función obtiene el control. Después de un tiempo, el control vuelve y la función se reanuda.

Ahora es el momento de avanzar hacia la implementación en Python. Discutiremos la parte de la sintaxis paso a paso y, al final, mostraremos el código completo.

Biblioteca y funciones de Python

El asyncio es una biblioteca en Python para escribir programas/funciones concurrentes utilizando la sintaxis async/await. El async es la palabra clave utilizada (para crear las funciones asíncronas) al comienzo de cada función.

La sintaxis es:

async def fun_a(t):

Aquí se agrega async para declarar esta función como una función asíncrona.

La función sleep puede suspender la ejecución de una rutina durante algún tiempo. Las corrutinas son los procesos/funciones que crean una estructura de tubería durante la ejecución.

Esta función deja voluntariamente la CPU para otra tarea cooperativa a través de la palabra clave await. La sintaxis de la función sleep es:

await asyncio.sleep(1)

Nota: Se requiere la palabra clave await para llamar a cada función asíncrona, ya sea de la biblioteca o una función definida por el usuario.

La palabra clave await devuelve el control al bucle de eventos. Puede considerar que si una función asíncrona llama con el comando await, la instrucción sleep (dentro del ciclo for) controla el proceso cooperativo hasta dormir.

La función reunir combina múltiples procesos cooperativos (técnicamente creando una rutina) para ejecutarse como una unidad. Esta función devuelve una tupla de resultados en el orden de las funciones escritas en la llamada gather.

La sintaxis es:

results = await asyncio.gather(fun_a(5), fun_b(5))

Aquí, estamos creando una canalización de fun_a y fun_b para que puedan ejecutarse simultáneamente.

El bucle de eventos es el ingrediente principal de toda aplicación asíncrona. Los bucles de eventos ejecutan funciones asincrónicas.

El método get_event_loop() comprueba si set_event_loop aún no se ha llamado, y creará un bucle de eventos y lo establecerá como actual. La sintaxis es:

my_loop = asyncio.get_event_loop()

Si este comando se ejecuta por segunda vez cuando el bucle ya está creado, no hará nada. Sin embargo, en la primera llamada no se crea ningún bucle; por lo tanto, creará un bucle asíncrono.

El run_until_complete() se utiliza para ejecutar el bucle de eventos simultáneamente si el bucle devuelto por get_event_loop() es asíncrono. La sintaxis es:

my_loop.run_until_complete(main())

Esta declaración ejecutará el código simultáneamente si la función main es asíncrona.

Código asíncrono

Teniendo una idea clara sobre el concepto y la biblioteca de Python requerida para ejecutar funciones/rutinas/procesos asincrónicos, es hora de ver un ejemplo de codificación completo:

import asyncio


async def fun_a(t):
    for i in range(t):
        print("fun_a", end=" ")
        await asyncio.sleep(1)
    return 1


async def fun_b(t):
    for i in range(t):
        print("fun_b", end=" ")
        await asyncio.sleep(1)
    return 2


async def main():
    results = await asyncio.gather(fun_a(5), fun_b(5))
    print(results)


my_loop = asyncio.get_event_loop()
my_loop.run_until_complete(main())

En este código, en la parte superior (la primera línea), estamos importando la biblioteca asyncio. Esta biblioteca tiene una función requerida para llamar a funciones asincrónicas para que se ejecuten simultáneamente; ya se discuten con la sintaxis.

A continuación, tenemos dos funciones asíncronas: fun_a y fun_b, que queremos ejecutar simultáneamente. Nuevamente, queremos llamar funciones asincrónicas desde la función principal. Por lo tanto, el principal también se crea como una función asíncrona.

Además, tenga en cuenta que pasamos 5 a nuestra función para ejecutar bucles dentro de ella cinco veces. Luego, puede ver la salida y hacerse una idea de que el bucle no se está ejecutando por completo; cada uno entra en un estado de suspensión y da control a la otra función.

Repetiremos este punto después de la salida.

Dentro de la función main, hemos llamado a la función gather y hemos pasado nuestras funciones asincrónicas para que puedan ejecutarse en paralelo. La función reunir devuelve una tupla, con dos valores devueltos por nuestras funciones asíncronas de destino.

Finalmente estamos llegando a las dos últimas líneas. En la penúltima línea, llamamos a la función get_event_loop para crear un bucle. En la última línea, usando nuestro bucle, llamamos a la función run_until_complete para comenzar a ejecutar nuestra función main de forma asíncrona.

La salida de este código es:

fun_a fun_b fun_a fun_b fun_a fun_b fun_a fun_b fun_a fun_b [1, 2]

Primero, tenga en cuenta que nuestros bucles no se ejecutan completamente como los códigos convencionales; en cambio, ambos bucles se ejecutan simultáneamente. Puede ver el resultado de ambas funciones print declaraciones.

Por último, [1, 2] es la tupla que recibe la función main de nuestras funciones asíncronas. Nuestras funciones asincrónicas devuelven 1 y 2 y se organizan en el orden en que escribimos estas funciones en la función reunir.

Artículo relacionado - Python Loop