epoll | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
NOM | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
SYNOPSIS | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
DESCRIPTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Un ensemble epoll est connecté à un descripteur de fichiers créé par epoll_create(2). L'interêt pour certains descripteurs est ensuite enregistré avec epoll_ctl(2). Enfin, l'attente effective démarre avec l'appel epoll_wait(2).
Sétection de niveau et détection de changement d'état | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Si le descripteur fd_lect a été ajouté à l'ensemble epoll en utilisant l'attribut EPOLLET (edge-triggered), l'appel epoll_wait(2), réalisé à l'étape 5, va probablement bloquer à cause des données toujours présentes dans les tampons d'entrée du fichier et le pair distant attendra une réponse basée sur les données qu'il a déjà envoyé. La raison en est que le mécanisme de distribution d'événements Edge Triggered délivre les événements seulement lorsque des événements surviennent sur le périphérique supervisé. Ainsi, à l'étape 5, l'appelant devrait cesser d'attendre des données qui sont déjà présentes dans le tampon d'entrée. Dans l'exemple ci-dessus, un événement sur fd_lect sera déclenché à cause de l'écriture à l'étape 2, et l'événement est consommé dans 3. Comme l'opération de lecture de l'étape 4 ne consomme pas toutes les données du tampon, l'appel à epoll_wait(2) effectué à l'étape 5 peut bloquer indéfiniment.
Une application qui utilise l'attribut EPOLLET devrait toujours utiliser des descripteurs non-bloquants pour éviter qu'une lecture ou une écriture bloque une tâche qui gère plusieurs descripteurs de fichiers. L'utilisation suggérée d'epoll avec l'interface en détection de changements (EPOLLET) est décrite ci-dessous :
Au contraire, lorsqu'il est utilisé avec l'interface en détection de niveau (ce qui est la valeur par défaut lorsque EPOLLET n'est pas spécifié), epoll est une alternative plus rapide à poll(2), et peut être employé chaque fois que poll() est utilisé, car il utilise la même sémantique.
Même dans un epoll de type Edge Triggered, plusieurs événements peuvent être générés à la réception de nombreux blocs de données. L'appelant peut, en spécifiant l'attribut EPOLLONESHOT, faire déactiver par epoll le descripteur de fichier associé, après la réception d'un événement avec epoll_wait(2). Lorsque l'attribut EPOLLONESHOT est spécifié, il est de la responsabilité de l'appelant de réarmer le descripteur en utilisant epoll_ctl(2) avec EPOLL_CTL_MOD.
Exemple d'utilisation conseillée | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
struct epoll_event ev, *events; for (;;) { nfds = epoll_wait(kdpfd, events, maxevents, -1); for (n = 0; n < nfds; ++n) { if (events[n].data.fd == listener) { client = accept(listener, (struct sockaddr *) &local, &addrlen); if (client < 0) { perror("accept"); continue; } setnonblocking(client); ev.events = EPOLLIN | EPOLLET; ev.data.fd = client; if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) == -1) { fprintf(stderr, "epoll set insertion error: fd=%d\n", client); return -1; } } else { do_use_fd(events[n].data.fd); } } }
Lorsqu'on utilise une détection de changement d'états, pour des raisons de performances, il est possible d'ajouter le descripteur de fichier dans l'interface epoll (EPOLL_CTL_ADD) une fois, en spécifiant (EPOLLIN|EPOLLOUT). Ceci évite de basculer sans cesse entre EPOLLIN et EPOLLOUT lors des appels epoll_ctl(2) avec EPOLL_CTL_MOD.
Questions et réponses | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Pour les fichiers orientés paquet/jeton (par exemple socket de datagramme, terminal en mode canonique), la seule façon de détecter la fin de l'espace d'E/S de lecture/écriture est de continuer à lire/écrire jusqu'à l'apparition de l'erreur EAGAIN. Quand et comment utiliser le descripteur dépend de vous.
Pour les fichiers orientés flux (par exemple, tube, FIFO, socket flux), la disponibilité des entrées-sorties peut-être vérifiée par la quantité de données lues ou écrites avec le descripteur. Par exemple, si vous appelez read(2) en demandant la lecture d'une certaine quantité de données et que read(2) en renvoie moins, vous pouvez être sûrs d'avoir consommé tout le tampon d'entrée pour le descripteur de fichiers. La même chose est vraie pour l'appel système write(2). (Évitez cette dernière technique si vous ne pouvez pas garantir que le descripteur de fichier surveillé fasse toujours référence à un fichier orienté flux.)
Pièges possibles et solutions | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Il est possible que durant une lecture (en supposant que vous lisez en boucle en attendant EAGAIN), des données supplémentaires arrivent en second événement. Bien que ces données soient lues tout de suite, l'appel suivant de epoll_wait(2) sur le descripteur dira qu'il y a un événement « lecture possible » alors qu'il a déjà été consommé.
Dans le cas de descripteurs non-bloquants, cela fera échouer immédiatement la lecture suivante avec l'erreur EAGAIN. Dans le cas de descripteurs bloquants, on restera en attente pour lire des données non encore présentes. L'auteur recommande de ne pas utiliser de descripteur bloquant avec le mécanisme de détection de changement d'état (ET).
Pour traiter ce cas, une possibilité est de marquer le descripteur comme prêt dans sa structure de données associée après la réception du premier événement, puis d'ignorer les événements tant qu'il est dans l'état prêt. Lorsque vous lisez jusqu'à recevoir EAGAIN, effacez le bit d'état prêt avant de rappeler epoll_wait(2) sur ce descripteur.
S'il y a un gros volume d'entrées-sorties, il est possible qu'en essayant de les traiter, d'autres fichiers ne soient pas pris en compte, ce qu'on appelle un cas de famine. Ce n'est pas spécifique à epoll.
La solution est de maintenir une liste de descripteurs prêts et de les marquer comme tels dans leur structure associée, permettant à l'application de savoir quels fichiers traiter, en organisant l'ordre au mieux. Ceci permet aussi d'ignorer les événements ultérieurs sur un descripteur prêt.
Si vous utilisez un cache d'événement, ou stockez tous les descripteurs renvoyés par epoll_wait(2), alors assurez vous de disposer d'un moyen de marquer dynamiquement leurs fermetures (causées par un événement précédent). Supposons que vous recevez 100 événements de epoll_wait(2), et que l'événement 47 implique de fermer le descripteur 13. Si vous supprimez la structure et utilisez close(2), alors votre cache peut encore contenir des événements pour ce descripteur, et poser des problèmes de cohérence.
Une solution est d'invoquer, pendant le traitement de l'événement 47, epoll_ctl(EPOLL_CTL_DEL) pour supprimer le descripteur 13, le fermer, et marquer sa structure associée comme supprimée. Si vous rencontrez un autre événement pour le descripteur 13 dans votre traitement, vous verrez qu'il a été supprimé précédemment, sans que cela ne prête à confusion.
VERSIONS | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
CONFORMITÉ | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
VOIR AUSSI | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
TRADUCTION | Début | Précédent | Suivant | Sommaire | Préc.page.lue | Accueil |
Ce document est une traduction réalisée par Christophe Blaess <ccb AT club-internet DOT fr> le 25 juillet 2003, mise à jour par Alain Portal <aportal AT univ-montp2 DOT fr> le 23 décembre 2005 et révisée le 6 juin 2008.
L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 4 epoll ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.
Sommaire | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
Table des mots clés | Début | Suivant | Sommaire | Préc.page.lue | Accueil |
1 | Pièges possibles et solutions |
2 | Pièges possibles et solutions |
3 | Pièges possibles et solutions |
4 | Pièges possibles et solutions |
5 | Pièges possibles et solutions |
6 | Pièges possibles et solutions |
A0 | Questions et réponses |
A1 | Questions et réponses |
A2 | Questions et réponses |
A3 | Questions et réponses |
A4 | Questions et réponses |
A5 | Questions et réponses |
A6 | Questions et réponses |
A7 | Questions et réponses |
A8 | Questions et réponses |
A9 | Questions et réponses |
o Famine (Edge Triggered) | Pièges possibles et solutions |
o Faux Positifs (Edge Triggered) | Pièges possibles et solutions |
o Utilisation d'un cache d'événements... | Pièges possibles et solutions |
Q0 | Questions et réponses |
Q1 | Questions et réponses |
Q2 | Questions et réponses |
Q3 | Questions et réponses |
Q4 | Questions et réponses |
Q5 | Questions et réponses |
Q6 | Questions et réponses |
Q7 | Questions et réponses |
Q8 | Questions et réponses |
Q9 | Questions et réponses |