CodeGym /Cursos /Python SELF ES /Introducción a tareas y el ciclo de eventos

Introducción a tareas y el ciclo de eventos

Python SELF ES
Nivel 25 , Lección 4
Disponible

5.1 Event Loop

Ahora vamos a hablar brevemente sobre la segunda parte de la asincronía, que nos ha estado rondando por todas partes: el ciclo de eventos (Event Loop), las tareas (Task) y Future.

Imagina el Event Loop como un director de orquesta, las Task como los músicos, y Future como las partituras que los músicos deben tocar. El director (Event Loop) coordina el trabajo de los músicos (Task), que interpretan la música (operaciones asíncronas), leyendo las partituras (Future).

El ciclo de eventos (Event Loop) es la base de la programación asíncrona en Python. Es responsable de ejecutar tareas asíncronas, gestionar eventos y procesar entrada-salida. El ciclo de eventos verifica continuamente la existencia de nuevos eventos o tareas y las inicia tan pronto como están listas.

Funciones principales

  • run_forever(): Inicia el ciclo de eventos y continúa su ejecución hasta que se llama a stop().
  • run_until_complete(future): Inicia el ciclo de eventos y lo finaliza tras completar el objeto futuro o la coroutine especificada.
  • stop(): Detiene el ciclo de eventos.
  • create_task(coroutine): Programa la ejecución de una coroutine como tarea.

Ejemplo de uso:


import asyncio

async def hello():
    print("Hello, world!")
    await asyncio.sleep(1)
    print("Hello again!")
            
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()

En este ejemplo, primero usamos el método get_event_loop() para obtener el objeto actual EventLoop de la biblioteca asyncio.

Luego, añadimos la coroutine hello a este EventLoop y le pedimos que lo ejecute utilizando el método run_until_complete().

En el último paso, cerramos el EventLoop usando el método close().

Al ejecutar este código, verás que primero se imprime "Hello, world!", luego el programa espera 1 segundo, y después de eso se imprime "Hello again!". Esto demuestra cómo el Event Loop gestiona la ejecución de una función asíncrona.

Estas acciones las estudiaremos más a fondo en la próxima lección.

5.2 Tasks

Las tareas (Tasks) son envoltorios para coroutines, que permiten gestionar su ejecución y supervisar su estado. Las tareas permiten ejecutar coroutines en paralelo, gestionándolas a través del ciclo de eventos.

Creación y gestión de tareas

  • asyncio.create_task(coroutine): Crea una tarea para la ejecución de una coroutine.
  • Task.result(): Devuelve el resultado de una tarea completada o lanza una excepción si la tarea finalizó con un error.
  • Task.cancel(): Cancela la ejecución de la tarea.

Ejemplo de uso:


import asyncio

async def say_hello():
    await asyncio.sleep(1)
    print("Hello")
            
async def main():
    task = asyncio.create_task(say_hello())
    await task
            
asyncio.run(main())

En este ejemplo, envolvemos la coroutine say_hello() con un objeto Task. También es un objeto asíncrono, por lo que para obtener su resultado, necesitamos aplicarle el operador await.

Al ejecutar este código, el programa espera 1 segundo y luego imprime "Hello". Esto muestra cómo Task gestiona la ejecución de una coroutine y cómo podemos esperar a su finalización con await.

Se hablará más en detalle sobre el trabajo con tareas Task en la próxima lección.

5.3 Futures

Los objetos Future representan el resultado de una operación asíncrona que estará disponible en el futuro. Permiten gestionar el estado de una operación asíncrona, estableciendo el resultado o la excepción.

Métodos principales:

  • set_result(result): Establece el resultado para el objeto Future.
  • set_exception(exception): Establece una excepción para el objeto Future.
  • result(): Devuelve el resultado del objeto Future o lanza una excepción si la operación finalizó con un error.
  • exception(): Devuelve la excepción, si fue establecida.

Ejemplo de uso:


import asyncio

async def set_future(fut, value):
    await asyncio.sleep(1)
    fut.set_result(value)
            
async def main():
    loop = asyncio.get_running_loop()
    fut = loop.create_future()
    await set_future(fut, 'Hello, future!')
    print(fut.result())
            
asyncio.run(main())

En este ejemplo, creamos un Future, establecemos su valor después de un segundo, y luego imprimimos el resultado. Verás que el programa espera un segundo antes de imprimir 'Hello, future!'. Esto demuestra cómo Future representa un resultado que estará disponible en el futuro.

A diferencia de un objeto Task, un objeto Future está vinculado a un Event Loop específico, y la función asíncrona ejecutada puede escribir en él su resultado. Aunque por lo general funciona un poco diferente.

Más a menudo, los objetos Future se usan en conjunto con tareas Task, que proporcionan un control de más alto nivel sobre las operaciones asíncronas.

Ahora que te has familiarizado con Event Loop, Task y Future, los estudiaremos más detalladamente.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION