Comprensión profunda de epoll

descripción general

En la programación de redes, el manejo eficiente de una gran cantidad de conexiones simultáneas es un tema clave. El mecanismo epoll proporcionado por Linux se ha convertido en una herramienta importante para resolver este problema. epoll es un mecanismo de notificación de eventos de E/S que realiza una programación concurrente impulsada por eventos de alto rendimiento a través de tres funciones principales, a saber, epoll_create, epoll_ctl y epoll_wait. Echemos un vistazo más profundo a estas tres funciones y cómo usarlas.

1. epoll_create - crea una instancia de epoll

int epoll_create(int size);

tamaño: el número de nodos de escucha del árbol rojo-negro creado. (Solo para referencia del kernel).
Valor devuelto: fd apuntando al nodo raíz del árbol rojo-negro recién creado.
-1: representa un error

2. epoll_ctl - controla los eventos de la instancia de epoll

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epfd: el valor de retorno de la función epoll_create. dfpe
op: la operación realizada en los números rojos y negros monitoreados.
EPOLL_CTL_ADD Agregue fd para escuchar el árbol rojo-negro.
EPOLL_CTL_MOD Modifique fd para escuchar los eventos de escucha en el árbol rojo-negro.
EPOLL_CTL_DEL Eliminar un fd del árbol rojo-negro de monitoreo (cancelar monitoreo)
fd: el fd que se monitoreará
evento: la estructura de esencia epoll_event puntero de estructura
valor de retorno: éxito 0; falla: -1 errno

Introducción a la estructura

struct epoll_event {
    
    
		__uint32_t events; /* Epoll events */
		epoll_data_t data; /* User data variable */
	};
	typedef union epoll_data {
    
    
		void *ptr;
		int fd;
		uint32_t u32;
		uint64_t u64;
	} epoll_data_t;

valor de eventos:

EPOLLIN: Indica que se puede leer el descriptor del archivo correspondiente (incluido el cierre normal del SOCKET peer)
EPOLLOUT: Indica que se puede escribir el descriptor del archivo correspondiente
EPOLLERR: Indica que el descriptor del archivo correspondiente tiene un error
, etc. (no importante)

datos: unión (comunidad):

int fd; fd void *ptr correspondiente al evento de escucha
; función de devolución de llamada
uint32_t u32;
uint64_t u64;

3. epoll_wait: espera a que ocurra un evento

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

La función epoll_wait se usa para esperar a que ocurra el evento y, cuando ocurra, devolverá el descriptor de archivo listo y el tipo de evento correspondiente. Los parámetros incluyen:

epfd: el valor de retorno de la función epoll_create. dfpe

events: Parámetros salientes, [array], aquellas estructuras fd que cumplen las condiciones de monitorización.

maxevents: el número total de elementos en la matriz anterior. por ejemplo: estructura epoll_event evnets[1024]->1024

tiempo de espera:
-1: bloqueo
0: no bloqueo
Mayor que 0: tiempo de espera (milisegundos)
valor devuelto:
mayor que 0: el número total de oyentes. Se puede utilizar como tapa de bucle.
0: No fd satisface el evento de escucha
-1: Error. error

inserte la descripción de la imagen aquí

pseudocódigo

Para la implementación del código, consulte: Link
epoll para realizar ideas de transferencia de E/S multicanal:

lfd = socket();			监听连接事件lfd
bind();
listen();

int epfd = epoll_create(1024);				epfd, 监听红黑树的树根。

struct epoll_event tep, ep[1024];			tep, 用来设置单个fd属性, ep 是 epoll_wait() 传出的满足监听事件的数组。

tep.events = EPOLLIN;					初始化  lfd的监听属性。
tep.data.fd = lfd

epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &tep);		将 lfd 添加到监听红黑树上。

while (1) {
    
    

	ret = epoll_wait(epfd, ep,1024-1);			实施监听

	for (i = 0; i < ret; i++) {
    
    
		
		if (ep[i].data.fd == lfd) {
    
    				// lfd 满足读事件,有新的客户端发起连接请求

			cfd = Accept();

			tep.events = EPOLLIN;				初始化  cfd的监听属性。
			tep.data.fd = cfd;

			epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &tep);

		} else {
    
    						cfd 们 满足读事件, 有客户端写数据来。

			n = read(ep[i].data.fd, buf, sizeof(buf));

			if ( n == 0) {
    
    

				close(ep[i].data.fd);

				epoll_ctl(epfd, EPOLL_CTL_DEL, ep[i].data.fd , NULL);	// 将关闭的cfd,从监听树上摘下。

			} else if (n > 0{
    
    --write(ep[i].data.fd, buf, n);
			}
		}
	}

Resumir

Mediante el uso de las tres funciones principales epoll_create, epoll_ctl y epoll_wait, podemos aprovechar al máximo el mecanismo epoll de Linux para lograr una programación concurrente eficiente basada en eventos. Primero, al crear una instancia de epoll, podemos monitorear múltiples descriptores de archivos. Luego, use la función epoll_ctl para agregar, modificar y eliminar eventos que necesitan ser monitoreados. Finalmente, espere a que ocurran los eventos y procese los descriptores de archivos listos llamando a la función epoll_wait.

El uso razonable de estas funciones puede ayudarnos a administrar de manera efectiva una gran cantidad de conexiones simultáneas y mejorar el rendimiento y la capacidad de respuesta del sistema. Por supuesto, en aplicaciones prácticas, también necesitamos combinar otros conocimientos y habilidades de programación de redes para lograr aplicaciones de red más estables y eficientes.

Supongo que te gusta

Origin blog.csdn.net/qq_46017342/article/details/132308231
Recomendado
Clasificación