- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
Ejemplo de programación de IO asíncrono de Python
En esta sección usaremos asyncio en Python 3.7 como ejemplo para explicar cómo usar la E / S asíncrona de Python.
Si aún no tiene Python 3.7 en su sistema, puede consultar el artículo del entorno virtual de Python para crear su entorno virtual de Python 3.7.
Crea la primera coroutina.
Python 3.7 recomienda usar la sintaxis async / await para declarar las rutinas para escribir aplicaciones asíncronas. Vamos a crear la primera función coroutine: primero imprima una línea de "hola", espere 1 segundo y luego imprima "sordos".
La función sayhi () se declara como una función de coroutine por async, que es más concisa que la declaración del decorador anterior.
En el proceso de la práctica, ¿qué funciones de función se deben declarar como una función de rutina con async? Las funciones que pueden realizar un rendimiento de E / S asíncrono, como leer y escribir archivos, leer y escribir redes y leer y escribir bases de datos, son operaciones de IO que requieren mucho tiempo, son coordinadas y asíncronas para mejorar la eficiencia (velocidad) general del programa.
La función sayhi () se ejecuta a través de
asyncio.run()
lugar de llamar directamente a esta función (coroutine). Debido a que la llamada directa no lo agrega a la programación de programación, sino que simplemente devuelve un objeto de rutina:
Entonces, ¿cómo se ejecuta realmente una coroutine? Asyncio proporciona tres mecanismos:
(1) función asyncio.run () , que es el punto de entrada principal para programas asíncronos, equivalente a la función principal en lenguaje C.
(2) Espere a que aparezca la coroutine a la espera , como
await asyncio.sleep(1)
en el ejemplo anterior. say_delay()
el siguiente ejemplo, definimos la corrutina say_delay()
, que se llama dos veces en main () coroutine, imprime "hola" después del primer retraso de 1 segundo, e imprime "sordos" después del segundo retraso de 2 segundos. ". Así que corremos dos coroutines a través de la espera.
Como se puede ver desde el inicio y el final, las dos rutinas se ejecutan de forma secuencial, lo que lleva un total de 1 + 2 = 3 segundos.
(3) Ejecute múltiples asociados de la tarea asyncio (Tarea) simultáneamente a través de la función
asyncio.create_task()
. A continuación, usamos create_task () para modificar el main () coroutine anterior, para que los dos say_delay () coroutines se ejecuten al mismo tiempo:
Se puede ver desde la hora de inicio y finalización del resultado de ejecución que las dos rutinas se ejecutan simultáneamente, y que el tiempo total transcurrido es igual al tiempo máximo de 2 segundos.
asyncio.create_task()
es una función útil que nos ayuda a implementar una gran cantidad de descargas simultáneas de páginas web en un rastreador. Correspondiente a ello en Python 3.6 es ensure_future()
.Objetos mobiliarios (aguardientes)
Los objetos que se pueden esperar son objetos que se pueden usar en las expresiones de espera. Ya hemos tocado dos tipos de objetos que se pueden esperar: coroutines y tareas, y un futuro de bajo nivel.
Muchas API en el módulo asyncio necesitan pasar objetos que se puedan esperar, como run (), create_task (), etc.
(1) Coroutine
Los coroutines son objetos que se pueden esperar y se pueden esperar en otros coroutines. Dos conceptos estrechamente relacionados de la corutina son:
- Función de Coroutine: una función definida por async def;
- Objeto coroutine: llama al objeto devuelto por la función coroutine.
Ejecuta el programa anterior, el resultado es:
co is now is 1548512708.2026224 now is 1548512708.202648
Como puede ver, la co obtenida ejecutando la función de coroutine whattime () directamente es un objeto de coroutine, porque el objeto de coroutine es waitable, por lo que la hora actual real se obtiene esperando. Now2 es una función de espera directa de coroutine, y también obtiene el valor de retorno de la hora actual.
(2) misión
Como mencionamos anteriormente, la tarea se usa para programar las coroutinas para ejecutarlas simultáneamente. Cuando un coroutine se empaqueta como una tarea a través de
asyncio.create_task()
, el coroutine se unirá automáticamente a la programación del programa y se preparará para ejecutarse de inmediato.
El uso básico de create_task () ya se ha cubierto en el ejemplo anterior. La tarea que devuelve está esperando que se ejecute a través de esperar. Si, no esperamos, ¿qué pasa? ¿Cómo entender "listo para correr de inmediato"? Echa un vistazo al siguiente ejemplo:


La situación con este código es la siguiente:
Primero, imprima una línea después de 1 segundo, que es el resultado de la 13ª, 14ª línea de código en ejecución:
Primero, imprima una línea después de 1 segundo, que es el resultado de la 13ª, 14ª línea de código en ejecución:
calling:0, now is 09:15:15
Luego, después de una pausa de 1 segundo, imprima 4 líneas seguidas:
calling:1, now is 09:15:16 calling:2, now is 09:15:16 calling:3, now is 09:15:16 calling:4, now is 09:15:16
A partir de este resultado, las cuatro tareas generadas por
asyncio.create_task()
, no tenemos que await
, también se ejecutan. La clave es la await
línea 18. Si elimina esta línea o duerme durante menos de 1 segundo (menos que el tiempo de suspensión en qué tiempo ()), solo verá la salida de la primera línea y no la verá. La salida de las siguientes cuatro líneas. Esto se debe a que main () no duerme ni duerme durante menos de 1 segundo, main () se cierra en el futuro (y porque duerme durante 1 segundo) y el programa completo se cierra. No hay salida de whattime ().
Entendamos la frase "listo para ejecutar inmediatamente ". Lo que significa es que create_task () simplemente empaqueta la rutina y se une a la cola de envío que aún no se ha ejecutado, y está listo para ejecutarse de inmediato. ¿Cuándo se ejecuta? Cuando el "coroutine principal" (el coroutine que llama a create_task ()) se cuelga, hay dos formas de "colgar" aquí:
Primero, realice esta tarea a través de la tarea de espera;
La otra es que la rutina principal se bloquea a través de la espera de espera, y el bucle de eventos ejecuta la tarea.
La otra es que la rutina principal se bloquea a través de la espera de espera, y el bucle de eventos ejecuta la tarea.
Sabemos que asyncio es asíncrono a través de bucles de eventos. En el main principal de coroutine (), cuando no se encuentra la espera, el evento es ejecutar la función main (). Cuando se encuentra la espera, el bucle del evento ejecuta otra coroutine, es decir, los cuatro de los whattime () generados por create_task (). Tareas, estas tareas comienzan con la espera de reposo durante 1 segundo. En este momento, la rutina principal y las cuatro tareas correspondientes están suspendidas, la CPU está inactiva y el bucle de eventos espera las noticias de la organización.
Si main () coroutine solo duerme 0.1 segundos, primero se despierta, envía un mensaje al ciclo de eventos y el evento continúa ejecutando main () coroutine. Después de que main () no tiene código, sale de la coroutine. Salir de él significa que todo el programa sale, y 4 tareas no tienen oportunidad de imprimir los resultados;
Si el tiempo de suspensión principal () es más de 1 segundo, entonces se activarán 4 tareas primero, y se obtendrán todos los resultados de impresión;
Si las 18 líneas de sueño principal () equivalen a 1 segundo, y el tiempo de reposo de las 4 tareas es el mismo, se obtendrán todos los resultados de impresión. Porque es esto
Supongo que este es el caso: primero se generan 4 tareas, y después del reposo en la línea 18, la respuesta del mensaje del bucle de eventos puede tener un orden de primero en entrar, primero en salir. El código que profundiza en asyncio está dedicado a la cuestión de si esta suposición es correcta o no.
(3) Futuro
Es un objeto que se puede esperar de bajo nivel que representa el resultado final de una operación asíncrona. En este momento, no lo usamos para escribir aplicaciones, y no aprendemos.
Asyncio asíncrono IO resumen coroutine
Una coroutina es un fragmento de nuestra operación asíncrona. Por lo general, el programa de escritura divide todas las funciones en funciones con muchas funciones diferentes con el propósito de una estructura clara. Además, las funciones que implican operaciones de E / S que requieren mucho tiempo (lectura y escritura de archivos, bases de datos y redes) son asincrónicas por async def, que es asíncrona. Programacion
Estas funciones asíncronas (funciones de coroutine) son programadas y administradas por el bucle de eventos. La ejecución de todo el programa es de un solo hilo. Sin embargo, cuando una determinada coroutine A realiza IO, el bucle de eventos ejecuta otras coroutines que no son IO. Codigo Cuando el bucle de eventos recibe el mensaje de que la rutina A termina el IO, regresa a la rutina A, de modo que el bucle del evento cambia continuamente entre ellas, haciendo un uso completo del tiempo de inactividad del IO, realizando simultáneamente múltiples operaciones de IO. Esto es IO asíncrono.
Recuerde una regla al escribir programas de E / S asíncronos: donde IO se necesita de forma asíncrona. Es inútil utilizar una función de coroutine en otros lugares.
留言
張貼留言