Frage

Mann 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.

Stellen Sie sich vor, wir haben zwei fds: die erste passiv ist, Daten nur manchmal verfügbar, die zweite aktiv ist, Daten nur manchmal nicht verfügbar

.

epoll_wait zurück, dass wir beide lesen können. Wir lesen {die erste, als die zweite} in einer Schleife (ohne Anrufe zu epoll_wait, weil es kann plötzlich blockieren, während die Daten noch verfügbar ist).

Nun ist die erste Dateideskriptor zurück EAGAIN auf zu lesen.

Was tun?

  1. Wenn wir gehen auf die zweite fd in einer Schleife zu lesen (ohne Anrufe zu epoll_wait), können wir vermissen, dass die Daten auf dem ersten fd verfügbar geworden sind. Es wird nur lesen und lesen und lesen, ohne EAGAIN.
  2. Wenn wir vor jedem Lesen aus dem zweiten fd „konsultieren“ mit epoll_wait werden, kann epoll_wait PLöTZLICH wegen aus dem vorherigen Anruf änderte nichts blockieren (Daten noch nicht verfügbar auf dem ersten FD und noch auf dem zweiten FD).

Wie die Verarbeitung des zweiten FD fortzusetzen, aber ohne sich um die erste FD zu vergessen?

Update: Gefunden noch etwas: Mann epoll_wait:

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

Damit ich Veranstaltungen für FDs sogar aufzählen kann, wenn es keine Ereignisse.

War es hilfreich?

Lösung

Wenn FD2 ständig lesbar Sie, dass epoll betrachten könnte, wird nicht für es für angemessen. Es könnte aus einem Thread wert Spinnen sein nur um es zu sitzen und zu lesen.

Ansonsten lesen FD2 in einer Schleife, bis er leer ist, aber in der Schleife hat es versucht, FD1 zu lesen einmal all X-mal durch. Wenn FD1 Daten hat, lesen Sie es. Wenn nicht werden Sie nur EAGAIN erhalten, setzen Sie den X-Zähler und gehen Sie zu lesen FD2 zurück. Wenn beide abgelassen werden, sind Sie zurück in epoll_wait.

So etwas wie:

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;
       }
   }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top