- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
IO asíncrona de Python: API
El asyncio de Python es una biblioteca estándar para escribir código concurrente usando la sintaxis async / await. A través de la explicación en la sección anterior, aprendimos sobre su historia cambiante. En la última versión de Python 3.7, asyncio ha hecho un gran ajuste. La API de esta biblioteca se divide en API de alto nivel y API de bajo nivel, e introduce métodos avanzados como asyncio.run () para hacer que los programas asíncronos sean más Conciso
Esta sección espera delinear la última versión 3.7 de asnycio; primero, comprenda la biblioteca de IO asíncrona de Python desde lo global.
La API de alto nivel de Asyncio mejora principalmente los siguientes aspectos:
- Ejecute Python coroutines simultáneamente y controle completamente su proceso de ejecución;
- Ejecutar red IO e IPC;
- Controlar el proceso hijo;
- Implementar tareas distribuidas a través de colas;
- Sincronizar código concurrente.
La API de bajo nivel de Asyncio se usa para apoyar el desarrollo de marcos y marcos asíncronos:
- Cree y administre bucles de eventos, proporcione API asíncronas para la red, ejecute procesos secundarios, procese señales del sistema operativo, etc.
- Implementar protocolos de alta eficiencia a través de transportes;
- Bibliotecas y código basados en devolución de llamada a través del puente de sintaxis async / await.
Asyncio API avanzada
Las API de alto nivel nos facilitan la escritura de aplicaciones basadas en asyncio. Estas API incluyen:
(1) Coroutines y tareas.
La rutina se declara con la sintaxis async / await y es la forma recomendada de escribir aplicaciones asíncronas. El historial
@asyncio.coroutine
y el yield from
han sido desaprobados y están programados para eliminarse en Python 3.10.asyncio.run(coro, *, debug=False)
se puede ejecutar a través de la función asyncio.run(coro, *, debug=False)
, que administra el bucle de eventos y finaliza el generador asíncrono. Debe utilizarse como el punto de entrada principal para el programa de asyncio, equivalente a la función principal, que solo debe llamarse una vez.
Las tareas se utilizan para la planificación simultánea de las rutinas y se pueden usar para rastreadores web simultáneos. Usando
asyncio.create_task()
puede empaquetar una rutina en una tarea, que se programa automáticamente para ejecutarse muy rápidamente.
Coroutines, tareas y futuros son todos objetos que se pueden esperar. Entre ellos, el Futuro es un objeto que se puede esperar de bajo nivel, que representa el resultado final de una operación asíncrona.
(2) flujo
Las secuencias son primitivas de alto nivel que utilizan async / await para conexiones de red. Las transmisiones permiten que los datos se envíen y reciban sin el uso de devoluciones de llamada o protocolos y transportes de bajo nivel. La lectura y escritura asíncronas TCP tiene la función de cliente
asyncio.open_connection()
y la función de servidor asyncio.start_server()
. También admite Unix Sockets: asyncio.open_unix_connection()
y asyncio.start_unix_server()
.(3) Primitiva de sincronización.
El diseño de la primitiva de sincronización de asyncio es similar a la primitiva del módulo de subprocesamiento. Hay dos consideraciones importantes:
Las primitivas asyncio no son seguras para subprocesos, por lo que no deben utilizarse para la sincronización de subprocesos del sistema operativo (pero con subprocesos)
Los métodos de estas primitivas de sincronización no aceptan parámetros de tiempo de espera, use la función
Asyncio tiene las siguientes primitivas básicas de sincronización:
Las primitivas asyncio no son seguras para subprocesos, por lo que no deben utilizarse para la sincronización de subprocesos del sistema operativo (pero con subprocesos)
Los métodos de estas primitivas de sincronización no aceptan parámetros de tiempo de espera, use la función
asyncio.wait_for()
para realizar operaciones de tiempo de espera.Asyncio tiene las siguientes primitivas básicas de sincronización:
- Bloqueo
- Evento
- Condicion
- Semáforo
- BoundedSemaphore
(4) Proceso del niño.
Asyncio proporciona API para crear y administrar procesos secundarios a través de async / await. A diferencia del subproceso de la biblioteca estándar de Python, las funciones del proceso hijo de asyncio son asíncronas y proporcionan una variedad de herramientas para manejar estas funciones, lo que facilita la ejecución y el monitoreo de varios procesos hijos en paralelo. Hay dos formas principales de crear un proceso hijo:
coroutine asyncio.create_subprocess_exec()
coroutine asyncio.create_subprocess_shell()
(5) Queue
El diseño de la cola de asyncio es similar a la clase de la cola del módulo estándar.Aunque las colas de asyncio no son seguras para subprocesos, están diseñadas para ser utilizadas exclusivamente para el código async / await. Tenga en cuenta que el método de cola de asyncio no tiene un parámetro de tiempo de espera, use la función
Debido a que es similar al diseño de clase de la cola del módulo de anotación, no hay mucha diferencia entre el uso y la cola. Simplemente agregue aguardar delante de la función correspondiente. La cola de asyncio proporciona tres colas diferentes:
asyncio.wait_for()
para realizar una operación de cola de tiempo de espera.Debido a que es similar al diseño de clase de la cola del módulo de anotación, no hay mucha diferencia entre el uso y la cola. Simplemente agregue aguardar delante de la función correspondiente. La cola de asyncio proporciona tres colas diferentes:
- Clase asyncio.Queue cola FIFO
- Clase de cola de prioridad asyncio.PriorityQueue
- Class asyncio.LifoQueue Último en la primera cola de salida
(6) Anormal
Asyncio proporciona varias excepciones, son:
- TimeoutError,
- Error cancelado,
- InvalidStateError,
- SendfileNotAvailableError
- IncompleteReadError
- LimitOverrunError
Asyncio API de bajo nivel
Las API de bajo nivel proporcionan soporte para escribir bibliotecas y marcos basados en asyncio, y aquellos interesados en escribir bibliotecas y marcos asíncronos deben estar familiarizados con estas API de bajo nivel. Principalmente incluyen:
(1) bucle de eventos
El bucle de eventos es el núcleo de cada aplicación de asyncio. El bucle de eventos ejecuta tareas asíncronas y devoluciones de llamada, realiza operaciones de E / S de red y ejecuta procesos secundarios.
Los desarrolladores de aplicaciones generalmente deben usar funciones asíncronas avanzadas, como
asyncio.run()
, y rara vez necesitan hacer referencia a objetos de bucle o llamar a sus métodos.
La función
asyncio.get_running_loop()
se ha agregado a Python 3.7.(2) Futuros
El objeto Future se usa para unir código de bajo nivel basado en devolución de llamada con código async / await de alto nivel.
El futuro representa el resultado final de una operación asíncrona. No hilo seguro.
El futuro es un objeto waitable. Coroutines puede esperar a los objetos futuros hasta que tengan un resultado o un conjunto de excepciones, o hasta que se cancelen.
Por lo general, los futuros se utilizan para habilitar el código basado en devolución de llamada de bajo nivel (por ejemplo, en los protocolos implementados utilizando el transporte asyncio) para interoperar con el código asincrónico / de espera de alto nivel.
El futuro representa el resultado final de una operación asíncrona. No hilo seguro.
El futuro es un objeto waitable. Coroutines puede esperar a los objetos futuros hasta que tengan un resultado o un conjunto de excepciones, o hasta que se cancelen.
Por lo general, los futuros se utilizan para habilitar el código basado en devolución de llamada de bajo nivel (por ejemplo, en los protocolos implementados utilizando el transporte asyncio) para interoperar con el código asincrónico / de espera de alto nivel.
(3) Transmisión y Protocolo (Transportes y Protocolos)
El transporte y el protocolo son utilizados por los bucles de eventos de bajo nivel, como la función
loop.create_connection()
. Utilizan un estilo de programación basado en la devolución de llamada y admiten implementaciones de alto rendimiento de protocolos de red o IPC, como HTTP.
En el nivel más alto, la transmisión implica la transmisión de bytes, y el protocolo determina qué bytes se transfieren (en cierta medida).
En otras palabras, el transporte es una abstracción de un socket (o un punto final de E / S similar), y el protocolo es una abstracción de la aplicación desde una perspectiva de transporte.
Otro punto de vista es que las interfaces de transporte y protocolo definen juntas una interfaz abstracta que utiliza la E / S de red y la E / S interproceso.
Siempre hay una relación 1: 1 entre el transporte y los objetos de protocolo: el protocolo llama al método de transporte para enviar datos, y el método de protocolo de llamada de transporte pasa los datos recibidos.
La mayoría de los métodos de bucle de eventos orientados a la conexión (como
loop.create_connection()
) generalmente aceptan el parámetro protocol_factory, que se usa para crear un objeto Protocol para la conexión aceptada, representado por el objeto Transport. Estos métodos suelen devolver tuplas (transporte, protocolo).(4) Política (Policy)
La estrategia de bucle de eventos es un objeto global que se divide por proceso y se usa para controlar la administración de los bucles de eventos. Cada ciclo de eventos tiene una política predeterminada que se puede cambiar y personalizar mediante la API de políticas.
Una política define el concepto de contexto y administra los bucles de eventos individuales según el contexto. La política predeterminada define el contexto como el hilo actual.
El comportamiento de las
get_event_loop()
, set_event_loop()
y new_event_loop()
se puede personalizar utilizando una estrategia de bucle de eventos personalizada.(5) Soporte de plataforma
El módulo asyncio está diseñado para ser portátil, pero debido a la arquitectura subyacente y la funcionalidad de la plataforma, existen algunas diferencias y limitaciones sutiles en algunas plataformas. En la plataforma Windows, algunos no son compatibles, como
loop.create_unix_connection()
y loop.create_unix_server()
. Linux y los macOS más nuevos son todos compatibles.Resumen
Python 3.7 aclara su arquitectura al agrupar asyncio. Las aplicaciones que escriben IO asíncronas solo necesitan estar familiarizadas con las API de alto nivel. Debe comprender las API de bajo nivel cuando necesita escribir bibliotecas y marcos para IO asíncronas.
留言
張貼留言