Explicación detallada del uso de epoll
Cada entrada en la tabla de descriptores a nivel de proceso registra información relacionada con un único descriptor de archivo.
1. Un conjunto de indicadores que controlan las operaciones del descriptor de archivos. (Actualmente, sólo se define uno de estos indicadores, el indicador de cierre al ejecutar)
2. Referencia al identificador de archivo abierto
Mantenimiento de archivos del kernel para todos los archivos abiertos Hay un tabla de descriptores a nivel de sistema (tabla de descripción de archivos abiertos). A veces, también se denomina tabla de archivos abiertos y cada entrada de la tabla se denomina identificador de archivos abiertos. Un identificador de archivo abierto almacena toda la información relacionada con un archivo abierto, de la siguiente manera:
1. Desplazamiento del archivo actual (actualizado al llamar a read() y write(), o usando lseek() Modificación directa) p>
2. El identificador de estado utilizado al abrir el archivo (es decir, el parámetro flags de open())
3. El modo de acceso al archivo (como cuando se llama a open()) La lectura -solo modo, modo de solo escritura o modo de lectura-escritura de la configuración)
4. Configuraciones relacionadas con el controlador de señal
5. Referencia al objeto i-nodo del file
6. Tipo de archivo (por ejemplo: archivo normal, socket o FIFO) y permisos de acceso
7. Un puntero a la lista de bloqueos que tiene el archivo
8. Varios atributos de los archivos, incluido el tamaño del archivo y las marcas de tiempo relacionados con diferentes tipos de operaciones
La siguiente figura muestra la relación entre los descriptores de archivos, los identificadores de archivos abiertos y los i-nodos. Los procesos tienen muchos descriptores de archivos abiertos.
Epoll: función de notificación de eventos de E/S
Traducido, epoll es un mecanismo de notificación de eventos de E/S. Esta oración contiene básicamente todos los puntos clave que deben entenderse:
p>epoll es un mecanismo que envía una señal legible para notificar cuando el búfer del núcleo del descriptor de archivo no está vacío, y envía una señal de escritura para notificar cuando el búfer de escritura no está lleno
El La interfaz de epoll es muy simple, con solo tres funciones:
los eventos pueden ser una colección de las siguientes macros:
EPOLLIN: indica que el descriptor de archivo correspondiente se puede leer (incluido el cierre normal). del par SOCKET);
EPOLLOUT: Indica que el descriptor de archivo correspondiente se puede escribir;
EPOLLPRI: Indica que el descriptor de archivo correspondiente tiene datos urgentes que se pueden leer (Esto debería indicar la llegada de datos fuera de banda);
EPOLLERR: Indica que el descriptor de archivo correspondiente tiene un error;
EPOLLHUP: Indica que el descriptor de archivo correspondiente está colgado;
EPOLLET: establece EPOLL en el modo Activado por flanco, que es relativo al Activado por nivel.
EPOLLONESHOT: solo escucha el evento una vez. Después de escuchar este evento, si aún necesita continuar monitoreando el socket, debe agregar el socket a la cola EPOLL nuevamente.
Primero pase create_epoll(int maxfds) para crear un identificador de epoll, donde maxfds es el número máximo de identificadores admitidos por su epoll. Esta función devolverá un nuevo identificador de epoll y todas las operaciones posteriores se realizarán a través de este identificador. Después de su uso, recuerde usar close() para cerrar el identificador de epoll creado.
Luego, en el bucle principal de su red, llame a epoll_wait(int epfd, epoll_event events, int max events, int timeout) para cada cuadro para consultar todas las interfaces de red para ver cuál se puede leer y cuál se puede. escribir. La sintaxis básica es:
nfds = epoll_wait(kdpfd, events, maxevents, -1);
donde kdpfd es el identificador creado con epoll_create y events es un puntero a epoll_event*. , cuando la función epoll_wait funciona correctamente, todos los eventos de lectura y escritura se almacenarán en epoll_events. max_events es el número de todos los identificadores de sockets que actualmente deben monitorearse. El último tiempo de espera es el tiempo de espera de epoll_wait. Cuando es 0, significa regresar inmediatamente. Cuando es -1, significa esperar hasta que haya un rango de eventos. Cuando es un número entero positivo, significa esperar tanto tiempo. Si no hay ningún evento, entonces alcance. Generalmente, si el bucle principal de la red es un subproceso separado, puede usar -1 para esperar, lo que puede garantizar cierta eficiencia. Si está en el mismo subproceso que la lógica principal, puede usar 0 para garantizar la eficiencia del bucle principal. .
Debería haber un bucle después del rango epoll_wait para recorrer todos los eventos.
Casi todos los programas epoll utilizan el siguiente marco:
A continuación se proporciona un ejemplo completo del lado del servidor: