es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo implementar en Python dos corutinas, manteniendo una en ejecución hasta que la otra termine.

Soy un traductor de español que traduce documentos informáticos. Traduzca lo siguiente al español. No traduzca el código y la salida en markdown.

Soy bastante nuevo en la biblioteca asyncio de Python y he estado golpeando mi cabeza para implementar una tarea de keep alive. Quiero ejecutar en paralelo una tarea intensiva de CPU y una tarea de keep alive. El keep alive debería ejecutarse periódicamente hasta que la tarea intensiva de CPU haya finalizado.

import asyncio
import time

async def cpuintensive():
    print("tarea intensiva de CPU durante 3 segundos")
    delay = 3
    closetime = time.time() + delay
    while True:
        if time.time() > closetime:
            break

async def keep_alive():
    print("keep alive durante 1 segundo") # Mi caso de uso real es que quiero enviar un mensaje de latido cada x segundos hasta que la tarea intensiva de CPU haya finalizado.
    await asyncio.sleep(1)

async def main():
    tarea_cpuintensiva = asyncio.create_task(cpuintensive())
    tarea_keepalive = asyncio.create_task(keep_alive())
    print(f"Comenzado en {time.strftime('%X')}")
    # TODO: No estoy seguro de cómo lograr la salida esperada
    print(f"Finalizado en {time.strftime('%X')}")

asyncio.run(main())

'''
Salida esperada
Comenzado en 23:55:08
tarea_intensiva de CPU durante 3 segundos
keep alive durante 1 segundos
keep alive durante 1 segundos
keep alive durante 1 segundos
Finalizado en 23:55:11
'''

He revisado la biblioteca asyncio de Python y he utilizado varias API como await, run_coroutine_threadsafe, asyncio.gather. Pero no pude hacer que funcionara.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Puedes usar asyncio.wait para lograr la salida esperada. asyncio.wait toma una lista de tareas y espera hasta que todas se completen. También puedes especificar un tiempo de espera.

    import asyncio
    import time
    
    async def procesamiento_intensivo():
        print("procesamiento intensivo por 3 segundos")
        delay = 3
        momento_cierre = time.time() + delay
        while True:
            if time.time() > momento_cierre:
                break
    
    async def mantener_activa():
        print("manteniendo activa por 1 segundo") # Mi caso de uso real es enviar un mensaje de latido cada x segundos hasta que se complete el procesamiento intensivo
        await asyncio.sleep(1)
    
    async def principal():
        tarea_procesamiento_intensivo = asyncio.create_task(procesamiento_intensivo())
        tarea_mantener_activa = asyncio.create_task(mantener_activa())
        print(f"Iniciado a las {time.strftime('%X')}")
        completadas, pendientes = await asyncio.wait([tarea_procesamiento_intensivo, tarea_mantener_activa], timeout=3)
        for tarea in pendientes:
            tarea.cancel()
        print(f"Finalizado a las {time.strftime('%X')}")
    
    asyncio.run(principal())
    

Comments are closed.