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.

cancelación automática de sub tareas en asyncio

Si una tarea asincrónica task_parent crea sub tareas task_child, pero task_parent es cancelada debido a una excepción que se produce después de que se haya creado task_child, ¿se cancela automáticamente también task_child (si no está protegida con asyncio.shield)?

Por ejemplo, en el siguiente código:

async def f():
    t1 = asyncio.create_task(coroutine1())
    t2 = asyncio.create_task(coroutine2())
    r1, = await asyncio.gather(t1)
    r3 = await process_result(r1) # process_result lanza una excepción
    r2, = await asyncio.gather(t2)
    return await process_results(r2, r3)

Si process_result(r1) lanza una excepción, ¿se cancela automáticamente t2 (y posteriormente se recolecta el garbage)?

Y qué pasa si en lugar de utilizar asyncio.gather, hago un await en una tarea directamente:

async def f():
    t1 = asyncio.create_task(coroutine1())
    t2 = asyncio.create_task(coroutine2())
    r1, = await t1
    r3 = await process_result(r1) # process_result lanza una excepción
    r2, = await t2
    return await process_results(r2, r3)

Si process_result(r1) lanza una excepción, ¿se cancela automáticamente t2 en este caso también?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Si task_child no está protegido con asyncio.shield, también se cancelará automáticamente cuando task_parent sea cancelado debido a una excepción. Esto se aplica a ambos casos presentados en la pregunta, ya sea utilizando asyncio.gather o esperando directamente en una tarea.

    En el caso del primer fragmento de código, si process_result(r1) genera una excepción, provocará que task_parent sea cancelado y como consecuencia, tanto t1 como t2 también serán cancelados.

    En el caso del segundo fragmento de código, si process_result(r1) genera una excepción, también se cancelará task_parent y como consecuencia, t2 también será cancelado.

    Sin embargo, si task_child está protegido con asyncio.shield, no se cancelará incluso si task_parent es cancelado. asyncio.shield se utiliza para proteger una tarea de ser cancelada, asegurando que completará su ejecución incluso si la tarea principal o todo el bucle de eventos es cancelado.

Comments are closed.