Frage

Die epoll manpage sagt, dass ein fd mit EPOLLET registriert (flankengetriggert) nicht zweimal EPOLLIN benachrichtigen, wenn keine Lese getan wurde.
Also nach einem EPOLLIN müssen Sie den Puffer leeren, bevor epoll_wait in der Lage, eine neue EPOLLIN auf neue Daten zurückzukehren.

Allerdings erlebe Ich habe Probleme mit diesem Ansatz, wie ich sehe duplizierten EPOLLIN Veranstaltungen für unberührten fds.
Dies ist der Strace Ausgang, 0x200 EPOLLRDHUP ist, die noch nicht in meinen glibc-Header definiert, aber im Kern definiert.

30285 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET|0x2000, {u32=9, u64=9}}) = 0
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3,  <unfinished ...>
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = 0
30306 recv(9, "7u\0\0\10\345\241\312\t\20\f\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30"..., 20000, 0) = 20000
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = -1 ENOENT (No such file or directory)
30305 recv(9, " \31(C0\17\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30\200\10 \31("..., 20000, 0) = 10011

Also, nach der Zugabe von fd Nummer 9 Ich erhalte 2 aufeinander folgende EPOLLIN Ereignisse bevor mit dem Dateideskriptor recving, die syscall Spur zeigt, wie ich das fd tun löschen, bevor das Lesen, aber es sollte nur einmal geschehen, ein pro Veranstaltung.
Also entweder ich bin nicht auf die Hilfeseite richtig zu lesen oder etwas arbeitet jetzt hier.

War es hilfreich?

Lösung

Ich glaube, du diesen Teil der epoll Manpage verpasst haben:

  

Da auch bei der flankengetriggerter   epoll können mehrere Ereignisse erzeugt werden   bei Empfang von mehreren Stücken von   Daten, hat der Anrufer die Möglichkeit,   geben die EPOLLONESHOT Flag, um   sagen epoll die zugehörige deaktivieren   Dateideskriptors nach dem Empfang   ein Ereignis mit epoll_wait(2). Wann   der EPOLLONESHOT Flag angegeben wird,   es liegt in der Verantwortung des Anrufers an   bewaffnen den Dateideskriptor mit   epoll_ctl(2) mit EPOLL_CTL_MOD.

Das heißt: Sie bekam zwei Stücke von Daten in Ihrer Empfangswarteschlange ankommen, bevor Sie Ihren ersten read() passiert ist, das heißt, Sie zwei epoll Ereignisse bekam. Es scheint, wie EPOLLONESHOT ist, was Sie nach, was atomar den Dateideskriptor aus der Umfrage Satz entfernen, wenn ein Ereignis auf es passiert (so dass Sie nicht brauchen die EPOLL_CTL_DEL zu tun).

Andere Tipps

Flankentrigger einfach Mittel (es sei denn, Sie gebrauchte EPOLLONESHOT haben), dass Sie ein Ereignis erhalten, wenn etwas eintritt, das (Kernel) puffern.

Wenn Sie also 1 EPOLLIN Veranstaltung erhalten und tun nichts dagegen, Sie eine andere EPOLLIN das nächste Mal kommt einige Daten auf diesem Descriptor bekommen - wenn keine neue Daten ankommen, werden Sie nicht ein Ereignis aber, auch wenn Sie lesen konnten keine Daten durch das erste Ereignis angezeigt wird.

Nun, um es kurz und bündig, EPOLLONESHOT nur bedeutet, dass, wenn Sie die Daten nicht lesen kann man eigentlich sind lesen, werden sie verworfen werden.

Normalerweise würde man mit einem Ereignis für die gleichen Daten benachrichtigt, wenn Sie sie nicht lesen. Mit EPOLLONESHOT jedoch nicht die Daten zu lesen ist vollkommen legal und werden sie einfach ignoriert werden. Daher werden keine weiteren Ereignisse erzeugt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top