Question

L'epoll man dit qu'un fd enregistré avec EPOLLET edge(déclenché) de ne pas informer les deux fois EPOLLIN si aucune lecture n'a été fait.
Ainsi, après une EPOLLIN vous avez besoin de vider la mémoire tampon avant epoll_wait être en mesure de retourner une nouvelle EPOLLIN sur de nouvelles données.

Cependant, je suis confronté à des problèmes avec cette approche que je vais voir des dupliqué EPOLLIN événements pour intactes fds.
C'est le strace sortie, 0x200 est EPOLLRDHUP qui n'est pas encore défini dans mes en-têtes glibc, mais définis dans le noyau.

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

Donc, après l'ajout de fd numéro 9 je reçois 2 consécutifs EPOLLIN événements avant d'avoir recving le descripteur de fichier, le syscall trace montre comment je dois supprimer le fd avant de le lire, mais il ne doit se produire une fois, un événement par événement.
Donc, soit je ne suis pas la lecture de la page de manuel correctement ou quelque chose qui est maintenant de travailler ici.

Était-ce utile?

La solution

Je pense que vous avez raté cette partie de la epoll l'homme page:

Car même avec le déclenchement epoll plusieurs événements peuvent être générés lors de la réception de plusieurs morceaux de de données, l'appelant a la possibilité de spécifiez le EPOLLONESHOT drapeau, dire epoll pour désactiver les associés descripteur de fichier à compter de la réception de un événement avec epoll_wait(2).Lorsque l' EPOLLONESHOT le drapeau est spécifié, c'est l'appelant responsabilité de réarmer le descripteur de fichier à l'aide de epoll_ctl(2) avec EPOLL_CTL_MOD.

C'est:vous avez deux blocs de données à l'arrivée dans votre file d'attente de réception avant votre premier read() qui s'est passé, ce qui signifie que vous avez deux epoll événements.Il semble que EPOLLONESHOT est ce que vous êtes après, qui sera automatiquement supprimer le descripteur de fichier à partir du sondage de définir quand un évènement se produit sur elle (donc vous n'aurez pas besoin de faire la EPOLL_CTL_DEL).

Autres conseils

Déclenchement sur front signifie simplement (sauf si vous avez utilisé EPOLLONESHOT) que vous obtiendrez 1 cas lorsque quelque chose entre l' (noyau) de la mémoire tampon.

Ainsi, si vous obtenez 1 EPOLLIN de l'événement et de ne rien faire à ce sujet, vous aurez une autre EPOLLIN la prochaine fois certaines données arrivent sur ce descripteur - si pas de nouvelles données arrivent, vous n'obtiendrez pas un événement, même si vous n'avez pas lu toutes les données comme indiqué par le premier événement.

Eh bien, pour résumer, EPOLLONESHOT signifie simplement que si vous ne lisez pas les données que vous êtes censé lire, ils seront jetés.

Normalement, vous auriez du être averti d'un événement pour les mêmes données si vous ne les lisent pas.Avec EPOLLONESHOT, cependant, pas de la lecture des données est parfaitement légal, et ils seront tout simplement ignorés.Par conséquent, plus aucun événement sera généré.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top