2010-01-18 14 views
7

¿Alguien puede ayudarme a responder las preguntas sobre epoll_wait.epoll rendimiento

  1. ¿Es una exageración de usar muchos hilos que llaman epoll_wait en los mismos FDS establecidas para servir a unos 100 K puertos activos? ¿o solo será suficiente crear solo 1 hilo para realizar epoll_wait?

  2. ¿Cuántos subprocesos se despertarán de epoll_wait cuando, por ejemplo, solo un socket está listo para leer datos? Quiero decir, ¿puede haber una situación en la que se despierten 2 o más hilos de epoll_wait pero tendrán los mismos fds en los eventos resultantes?

  3. ¿Cuál es la mejor manera de organizar subprocesos en el servidor que funciona con muchos clientes activos (por ejemplo, 50K +). La mejor manera en que pienso es: 1 E/S Trabajador Subproceso que realiza epoll_wait y operaciones de E/S. + Muchos hilos de procesamiento de datos que procesarán los datos recibidos del hilo de trabajo de E/S (puede llevar mucho tiempo, como cualquier lógica de juego) y componen nuevos datos para el hilo de trabajo de E/S para enviar al cliente. ¿Estoy en lo correcto en este enfoque, o alguien puede ayudarme a encontrar la mejor manera de organizar esto?

Gracias de antemano, Valentin

Respuesta

7
  1. Al utilizar epoll, desea el tamaño total de su hilo con el número de núcleos de CPU físicas (o hyperthread unidades de envío) que desea utilizar para el procesamiento. Usar solo un hilo para el trabajo significa que como máximo un núcleo estará activo a la vez.

  2. Depende del modo del descriptor del archivo epoll. Los eventos pueden ser "activados por flanco", lo que significa que solo suceden una vez de forma atómica, o "nivel disparado", lo que significa que cualquier persona que llama obtiene un evento si hay espacio en el búfer.

  3. No hay suficiente información para decir. Sugiero no tener ningún hilo de propósito especial, por simplicidad, y simplemente manejar el "comando" de cada evento en el hilo en el que se recibe. Pero obviamente eso depende de la naturaleza de su aplicación.

+0

Por lo tanto, si entendí correctamente, el mejor esquema se ve de la siguiente manera: Cree el número de hilos de E/S igual al número de núcleos en el sistema y use ET epoll_wait. Cada hilo tendrá su propio subconjunto de fd. Por ejemplo, 4 hilos para el procesador IC2Q. Cada hilo maneja conexiones de 25K y en total 100K. Y la siguiente pregunta: ¿Necesito tener un hilo separado que pegue epoll_wait socket de escucha y administre en qué subconjunto del socket recién aceptado se agregará?¿Y es seguro para subprocesos agregar fd recién aceptado utilizando epoll_ctl en un subproceso, mientras que otro está haciendo epoll_wait en este subconjunto? – Valentin

+0

Esperaría en todos los descriptores en todos los hilos, en realidad. A menos que sepa que puede ganar en los efectos de caché aislando el trabajo relacionado en CPU específicas, generalmente es una pérdida hacer ese tipo de particiones. Terminas muriendo de hambre con una CPU mientras que otra todavía tiene trabajo que podría hacerse. Y sí: las operaciones de epoll son atómicas (aunque, obviamente, necesitarás bloquear tu propio bookeeping). –

+0

¿Cómo se comportará ET epoll_wait? ¿Se despertarán todos los hilos de epoll_wait? ¿O solo 1 hilo? Si entendí correctamente, ET epoll_wait es atómico y sucederá solo una vez para fd listos. Por ejemplo: tengo 2 fds y 2 hilos esperando en epoll_wait. 1 fd está listo y solo se reanudará 1 hilo y si otro fd estará listo durante la primera conversación con el primer fd, se reanudará el segundo. Andy, ¿es esto correcto? – Valentin

-1

En realidad este es un caso de uso incorrecto de epoll.

No debe compartir el epoll fd entre subprocesos. De lo contrario, tiene la posibilidad de que un hilo lea parte de los datos entrantes en un fd y otro subproceso también en el mismo fd sin ninguna forma de saber qué parte de los datos estaba antes que el otro.

Simplemente llame a epoll_create en cada hilo que llame a epoll_wait. De lo contrario, la E/S está rota.

+0

Me parece que estás confundiendo el epoll fd con el fd del socket real. Usar epoll en múltiples hilos es absolutamente posible, de hecho, ese es uno de los puntos para usarlo. Para no tener una condición de carrera entre los hilos, debe usar 'EPOLLONESHOT' o, en los núcleos más nuevos,' EPOLLEXCLUSIVE'. [Este excelente blog] (https://idea.popcount.org/2017-02-20-epoll-is-fundamentally-broken-12/) explica los detalles. – kralyk