Cómo leer múltiples descriptores de archivos utilizando epoll_select con EPOLLET?

StackOverflow https://stackoverflow.com/questions/4003804

  •  25-09-2019
  •  | 
  •  

Pregunta

hombre epoll:

The suggested way to use epoll as an edge-triggered (EPOLLET) interface is as follows:
    i   with nonblocking file descriptors; and
    ii  by waiting for an event only after read(2) or write(2) return EAGAIN.

Imaginemos que tenemos dos FDS: el primero es pasivo, los datos disponibles sólo a veces, la segunda está activo, los datos sólo a veces no disponible

.

epoll_wait devueltos que podemos leer tanto. {Leemos la primera, que el segundo} en un bucle (sin llamadas a epoll_wait debido a que pueden bloquear repentinamente mientras que los datos aún está disponible).

Ahora el primer descriptor de archivo devuelto EAGAIN de lectura.

¿Qué hacer?

  1. Si continuamos leyendo la segunda fd en un bucle (sin llamadas a epoll_wait), podemos perder los datos que se han convertido en disponible en el primer fd. Se acaba de leer y leer y leer sin EAGAIN.
  2. Si vamos a "consultar" con epoll_wait antes de cada lectura de la segunda fd, epoll_wait de repente puede bloquear a causa de nada cambió desde la llamada anterior (datos aún no está disponible en el primer FD y todavía disponible en el segundo FD).

¿Cómo continuar el procesamiento de la segunda FD, pero sin dejar de lado el primer FD?

Actualización: Encontrados una cosa más: hombre epoll_wait:

while specifying timeout equal to zero makes epoll_wait() to return immediately even if no events are available

Con esto puedo enumerar eventos para FDs incluso si no hay eventos.

¿Fue útil?

Solución

Si FD2 se puede leer constantemente que podría considerar que epoll no es apropiado para ella. Puede ser que valga la escisión de un hilo sólo para sentarse y lo leyó.

De lo contrario, lea FD2 en un bucle hasta que se drena, pero en el bucle tiene que intenta leer FD1 una vez cada X veces a través. Si tiene datos FD1, leerlo. Si no vas a tener EAGAIN, restablecer el contador X y volver a leer FD2. Cuando ambos son drenados que están de vuelta a epoll_wait.

Algo así como:

count = 1;

while (true)
{
   read fd2;

   if (EAGAIN)
       break;
   else
       process data;

   count--;

   if (! count)
   {  
       while (true)
       {
           read fd1;

           if (EAGAIN)
               count = 10;
               break;
           else
               process data;
       }
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top