Quien te pregunte qué es multiplexar io en el futuro será pateado en la placa de acero.

io es el área más afectada para muchos desarrolladores de Java / python / go. Si nunca ha estado involucrado en el desarrollo, es posible que solo sepa sobre bloqueo / no bloqueo, sincrónico / asincrónico y, más poderosamente, multiplexación.
inserte la descripción de la imagen aquí
Muchos estudiantes no tienen idea sobre estos conceptos Sin una comprensión clara, en realidad es solo leer y recitar el texto completo ~

Hoy, lo llevaré a explorar el historial de desarrollo de io. Si alguien le pregunta sobre io en el futuro, simplemente pateará la placa de acero.
inserte la descripción de la imagen aquí

Hay tantos artículos sobre io en Internet, pero es posible que hayas visto el siguiente párrafo por primera vez (si lo entiendes, léelo, si no lo entiendes, sáltatelo, y lo entenderás naturalmente cuando tú lo entiendes):

Ya sea Windows o Linux, todas las operaciones relacionadas con io no pueden ser completadas directamente por el programa de aplicación. Es muy peligroso abrir permisos de operación de archivos a los usuarios. Si desea realizar operaciones io, debe usar las funciones proporcionadas por el sistema operativo. kernel, pero estas funciones no necesitamos llamarlo personalmente. Java ya ha hecho un buen trabajo de encapsulación para nosotros. Podemos ajustar la api relevante durante el desarrollo. Como se muestra en la figura a continuación, los dos paquetes
inserte la descripción de la imagen aquí
io son de lectura simple /write, y nio introduce tres nuevos conceptos:

  • Búfer: contenedor de datos;
  • Canal: Esta cosa es demasiado abstracta. El nombre chino es canal. Basta saber que puede completar la operación io entre núcleos;
  • Selector: nio implementa la base para multiplexación;

Ok, después de decir tonterías, primero clasifiquemos los conceptos relevantes.

  • Síncrono o asíncrono : Síncrono significa ejecutarse de manera ordenada, y la siguiente tarea se ejecutará después de que se ejecute la tarea actual; por el contrario, otras tareas no necesitan esperar a que se ejecute la tarea actual y, por lo general, dependen de eventos. y mecanismos de devolución de llamada para realizar la relación de orden entre tareas;
  • Bloqueo y no bloqueo : cuando se realiza una operación de bloqueo, el subproceso actual estará en un estado bloqueado y no podrá participar en otras tareas. Solo puede continuar cuando las condiciones estén listas, como lectura y escritura de datos; medios sin bloqueo que independientemente de que finalice la operación IO, la devolución.

Con solo mirar el concepto, el cerebro está zumbando, no importa, mira la pantalla grande ~

arroz cocido

Hay un restaurante de celebridades de Internet cerca de la empresa. Hay muchas señoritas que van a cenar a su casa todos los días. Por supuesto, no me malinterpreten. Solo quiero decir que sus comidas son muy buenas. Ah. .. No, quiero decir que sus señoritas son muy buenas Delicioso, ugh... no está bien

En resumen, voy allí a menudo y mi método de pedido ha experimentado las siguientes versiones :

  • v1.0 : Cuando fui allí por primera vez, vi que otras personas estaban haciendo cola para pedir comida. Como persona honesta, solo puedo esperar a que la persona de enfrente termine de ordenar antes de ordenar, y luego ir al puerto de recogida. y esperar a que recojan la comida. A veces me toma 15 minutos recibir la comida, pero puedo ver a más señoritas y hermanas de pie en el puerto de recogida de la comida, así que al principio no me importó;
  • v2.0 : Un día después, descubrí que había una pantalla sobre el puerto de recogida de alimentos, que mostraba el pedido actual del número de pedido. Wow, de repente me di cuenta de que a partir de ese momento, cada vez que terminara de hacer un pedido, encontraría un lugar donde hay muchas damas y hermanas para sentarse, luego vengan al puerto de recogida cada 5 minutos para ver si me toca a mí recoger la comida;
  • v3.0 : Con el tiempo, me cansé de mirar a la señorita y a la hermana todos los días. Un día encontré un código QR en la mesa. Wow, de repente me di cuenta de que puedo pedir comida escaneando el código. Entregaré comidas a su ubicación;

La relación entre la recogida de comida y io :

  • v1.0 (bio, bloqueo de io) : hacer cola para ordenar y esperar comida, similar a bio, bloqueo síncrono, después de que el subproceso envía la operación io, no puede regresar antes de que se complete la operación io, ni puede hacer otras cosas , y sólo puede esperar torpemente ;
  • v2.0 (nio, io sin bloqueo) : haga cola para pedir, vaya al puerto de recogida de vez en cuando para ver si es su turno de recoger la comida, similar a nio, sin bloqueo sincrónico, el subproceso puede regresar primero después de enviar la operación io, pero debe buscar activamente la operación. El sistema obtiene el resultado (nio puede compilar io multiplexado, que es el tema central de este artículo);
  • v3.0 (nio2, o aio, io asíncrono) : escanee el código para ordenar, encuentre un lugar para sentarse y observar a la dama después de ordenar, y el mesero lo entregará después de la comida, similar a aio, asíncrono y sin bloqueo , en Sobre la base de nio, se agrega un evento y un mecanismo de devolución de llamada.Después de que el sistema operativo prepare los datos, notificará activamente al subproceso.

Con respecto al soporte de funciones del sistema operativo para io a nio, el proceso de evolución es más complicado. Debe comprender cómo el sistema operativo implementa la copia cero. Pase a Análisis de tecnología de copia cero.

Acerca de io / nio, de hecho, son solo las cosas anteriores, no se confunda, hoy nuestro tema es multiplexar io

Las reglas antiguas, vamos a arrojar primero algunas de las dudas más comunes de los hermanos, y estas dudas serán respondidas a continuación:

  • ¿Qué es la multiplexación?
  • ¿Por qué necesita multiplexación?
  • ¿Qué problema resuelve la multiplexación?
  • ¿Qué es exactamente la multiplexación y qué es la multiplexación?

La comunicación de red tradicional utiliza sockets y el proceso es el siguiente:

  1. crear zócalo
  2. Vincule la IP y el puerto del servidor actual al socket
  3. Escuche en el puerto y procese las solicitudes a través de aceptar

No hay nada de malo en el proceso, pero debe saber que aceptar es bloquear, lo que significa que solo se puede procesar una solicitud al mismo tiempo . Si desea procesar varias solicitudes al mismo tiempo, puede usar subprocesos múltiples, pero esto causará otro problema: operación Cuando hay demasiados subprocesos en el sistema, necesita gastar muchos recursos para administrar los subprocesos y el cambio de contexto (aquí hay una oración larga, sin importar el escenario, cuantos más subprocesos, mejor , después de alcanzar un cierto umbral, cuantos más subprocesos, menor es la eficiencia)

Por lo tanto, para manejar correctamente múltiples solicitudes al mismo tiempo, el kernel del sistema operativo debe implementar un solo hilo para escuchar múltiples sockets, es decir, multiplexación io

Hay tres tipos de soporte para multiplexación en el sistema Linux:

  • Multiplexación: seleccione
  • Pro de multiplexación: encuesta
  • Multiplexación pro max: epoll

Echemos un vistazo a la implementación de estas tres funciones, y el desempeño de las tres probablemente sea claro.

Seleccione

//返回值是已就绪文件描述符个数
int select (int __nfds, fd_set *__readfds, fd_set *__writefds, fd_set *__exceptfds, struct timeval *__timeout)

Explicación de parámetros:

  • _ _nfds: El número de descriptores de archivo monitoreados (no se preocupe por lo que es un descriptor de archivo, se puede entender que cada operación io corresponde a un descriptor de archivo);
  • _ _readfds, __writefds, __exceptfds: especifique los tipos de eventos monitoreados por el mecanismo de multiplexación, estos tres son eventos de lectura de datos, eventos de escritura de datos y eventos de excepción;
  • _ _timeout: El tiempo de espera para bloquear y esperar al escuchar;

select administra múltiples conexiones al monitorear múltiples descriptores de archivos, y puede monitorear 1024 a la vez (el valor predeterminado).Cuando la función select regresa, atraviesa el conjunto de descriptores para encontrar el descriptor listo para el siguiente paso.

Hasta ahora, el problema de que un subproceso solo puede administrar una conexión está resuelto, pero todavía hay dos problemas:

  • El número de descriptores monitoreados cada vez es limitado, aunque puede modificarse modificando el archivo de macro, este enfoque es demasiado extremo;
  • Necesitamos ejecutar continuamente la función de selección para obtener descriptores de archivos listos, y el proceso transversal también consume rendimiento de la CPU;

Entonces, Linux introdujo la encuesta para resolver el problema de las restricciones del descriptor de archivos.

encuesta

//返回值也是已就绪文件描述符个数
int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);

Explicación de parámetros:

  • _ _fds: una matriz de estructuras pollfd, incluido el descriptor de archivo que se monitoreará y el tipo de evento que se monitoreará;
  • _ _nfds: el número de matrices de estructura pollfd, no hay límite de tamaño;
  • _ _timeout: El tiempo de espera para bloquear y esperar al escuchar;

En comparación con la selección, la encuesta en realidad supera la limitación de los descriptores de archivos, pero aún necesitamos recorrer cada descriptor de archivo para detectar si está listo.

Entonces, Linux2.6 introdujo epoll

encuesta

epoll tiene tres funciones epoll_create, epoll_ctl y epoll_wait

//创建epoll实例,size表示监听多少个文件描述符
int epoll_create(int size)//将连接加入epoll监听列表,参数分别表示:
//epoll_create()的返回值
//需要执行的修改操作
//需要监听的文件描述符
//监听的事件类型
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)//阻塞等待返回已就绪的文件描述符,参数分别表示:
//epoll_create()的返回值
//事件的集合
//events大小
//超时时间
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

El modelo epoll admite la cantidad de descriptores que se monitorearán y también puede devolver directamente descriptores listos

La implementación del famoso redis en el sistema Linux se basa en el modelo epoll, por lo que incluso si se trata de un solo hilo, puede hacer frente fácilmente a un alto acceso de clientes concurrentes.


Habiendo dicho tanto, ¿qué es exactamente la multiplexación io? ¿Qué se reutiliza?

Creo que estas dos preguntas son difíciles de explicar, tal vez realmente lo entienda cuando realmente entre en contacto con el conocimiento del sistema operativo en el futuro.

Opinión personal sobre la reutilización:

En primer lugar, definitivamente no es la multiplexación de sockets, una solicitud correspondiente a un socket no se puede cambiar aunque venga Jesús;

No es una reutilización de subprocesos, pero parece comprensible, porque después de todo, un subproceso administra múltiples sockets;

La llamada reutilización puede no tener que reutilizar cierta cosa, creo que es el comportamiento de administrar múltiples sockets a través de una solicitud al kernel.


Es suficiente para comprender las diversas funciones mencionadas anteriormente. No es necesario estudiar demasiado profundamente. También he leído muchos documentos para obtener esta información. No es necesario dedicar demasiado tiempo a ello, de lo contrario mi cerebro estar zumbando ~, solo estoy pensando en eso ahora. Zumbando, efectivamente, cuanto más sabes, menos entiendes. . .

Ok. Ya terminé

Supongo que te gusta

Origin blog.csdn.net/qq_33709582/article/details/123137787
Recomendado
Clasificación