loop - PEP 0492-Palabra clave async de Python 3.5
python async api (1)
PEP 0492 agrega la palabra clave async
a Python 3.5.
¿Cómo se beneficia Python del uso de este operador? El ejemplo que se da para una corrutina es
async def read_data(db):
data = await db.fetch(''SELECT ...'')
De acuerdo con los documentos esto logra
suspender [ing] la ejecución de read_data coroutine hasta que db.fetch awaitable complete y devuelva los datos del resultado.
¿Esta palabra clave async
realmente involucra la creación de nuevos hilos o quizás el uso de un hilo asincrónico reservado existente?
En el caso de que async
sí use un hilo reservado, ¿se trata de un único hilo compartido cada uno por su cuenta?
No, las co-rutinas no involucran ningún tipo de subprocesos. Las co-rutinas permiten la multitarea cooperativa en el sentido de que cada co-rutina cede voluntariamente el control. Los hilos, por otro lado, cambian entre unidades en puntos arbitrarios.
Hasta Python 3.4, era posible escribir co-rutinas usando generadores ; al usar el yield
o el yield from
expresiones en un cuerpo de función, en su lugar crea un objeto generador, donde el código solo se ejecuta cuando itera sobre el generador. Junto con bibliotecas de bucles de eventos adicionales (como asyncio
), podría escribir co-rutinas que asyncio
a un bucle de evento que iban a estar ocupadas (esperando E / S tal vez) y que podría ejecutarse otra co-rutina en el mientras tanto:
import asyncio
import datetime
@asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
Cada vez que el código anterior avanza al yield from asyncio.sleep(1)
, el ciclo de eventos es libre de ejecutar una co-rutina diferente, porque de todos modos esta rutina no va a hacer nada para el próximo segundo.
Debido a que los generadores se pueden utilizar para todo tipo de tareas, no solo rutinas conjuntas, y porque escribir una co-rutina utilizando la sintaxis del generador puede ser confuso para los recién llegados, el PEP introduce una nueva sintaxis que deja en claro que usted está escribiendo una co -rutina.
Con el PEP implementado, la muestra anterior podría escribirse en su lugar como:
async def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(1)
El objeto coroutine
resultante todavía necesita un bucle de eventos para controlar las co-rutinas; un ciclo de eventos await
en cada co-rutina a su vez, lo que ejecutaría aquellas co-rutinas que actualmente no están await
que se complete algo.
Las ventajas son que con soporte nativo, también puede introducir sintaxis adicional para admitir gestores e iteradores de contexto asíncrono. Ingresar y salir de un administrador de contexto, o recorrer un iterador puede convertirse en más puntos en su co-rutina que indiquen que otro código puede ejecutarse en su lugar porque algo está esperando nuevamente.