Provided by: manpages-fr_3.32d0.2p4-1_all bug

NOM

       epoll - Notifications d'événements d'entrées-sorties

SYNOPSIS

       #include <sys/epoll.h>

DESCRIPTION

       epoll  est  une variante de poll(2) que l'on peut déclencher par niveau
       ou par changement d'état, et monte bien en charge pour un grand  nombre
       de  descripteurs  simultanés.  Les appels système suivants sont fournis
       pour créer et superviser une instance epoll :

       *  Une  instance  epoll  créée  par  epoll_create(2),  qui  renvoie  un
          descripteur de fichier référençant l'instance epoll (la version plus
          récente    epoll_create1(2)    étend    les    fonctionnalités    de
          epoll_create(2)).

       *  L'intérêt pour un descripteur de fichier est ensuite enregistré avec
          epoll_ctl(2). L'ensemble des descripteurs de  fichiers  actuellement
          enregistrés  pour  une instance epoll est parfois appelé un ensemble
          epoll.

       *  Enfin, l'attente est effectivement démarrée avec epoll_wait(2).

   Détection de niveau et détection de transition
       L'interface de distribution d'événements de epoll  est  capable  de  se
       comporter en détection de niveau (Level Triggered - LT) ou en détection
       de transition (Edge Triggered -  ET).  La  différence  entre  ces  deux
       mécanismes est décrite ci-dessous. Supposons que le scénario suivant se
       produise :

       1. Le descripteur de fichier qui représente le côté lecture  d'un  tube
          (rfd) est enregistré dans l'instance epoll.

       2. Celui qui écrit dans le tube envoie 2 Ko de données.

       3. Un   appel  à  epoll_wait(2)  est  effectué  et  renvoie  rfd  comme
          descripteur de fichier prêt.

       4. Le lecteur du tube lit 1 Ko de données depuis rfd.

       5. Un appel de epoll_wait(2) est effectué.

       Si le descripteur rfd 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  bien  qu'il  y  ait  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ées.   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 fichier supervisé. Ainsi, à l'étape
       5, l'appelant peut 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 rfd 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 verrouiller indéfiniment.

       Une  application  qui  emploie  l'attribut EPOLLET de la fonction epoll
       devrait toujours utiliser des descripteurs non  bloquants  pour  éviter
       qu'une lecture ou une écriture ne bloque, par une famine, une tâche qui
       gère  plusieurs  descripteurs  de  fichier.  L'utilisation   préconisée
       d'epoll  avec  l'interface en détection de changements (EPOLLET) est la
       suivante :

              i   avec des descripteurs non bloquants ; et

              ii  en attendant seulement après qu'un read(2) ou un write(2)  a
                  renvoyé EAGAIN.

       Au  contraire,  lorsqu'il  est utilisé avec l'interface en détection de
       niveau (par défaut si  EPOLLET  n'est  pas  spécifié),  epoll  est  une
       alternative plus rapide à poll(2), et peut être employé chaque fois que
       ce dernier 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ésactiver 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.

   Interfaces /proc
       Les  interfaces  suivantes  peuvent  être  utilisées  pour  limiter  la
       quantité de mémoire du noyau utilisée par epoll :

       /proc/sys/fs/epoll/max_user_watches (depuis Linux 2.6.28)
              Ceci  définit  une  limite  au  nombre  total de descripteurs de
              fichiers qu'un utilisateur peut enregistrer au travers de toutes
              les  instances  epoll  du  système.  La  limite  est imposée par
              identifiant d'utilisateur réel. Chaque  descripteur  de  fichier
              enregistré  coûte  environ  90 octets  sur  un  noyau 32 bits et
              environ 160 octets sur un noyau 64 bits. Actuellement la  valeur
              par  défaut pour max_user_watches est de 1/25 (4%) de la mémoire
              basse disponible, divisé par le coût d'allocation en octets.

   Exemple d'utilisation
       Tandis que l'utilisation de epoll  avec  un  déclenchement  par  niveau
       correspond  à  la  même  sémantique  que  poll(2), le déclenchement par
       changement d'état nécessite plus d'explication pour éviter les  cas  de
       blocage.  Dans cet exemple, le lecteur emploie une socket non bloquante
       sur laquelle listen(2)  a  été  appelée.  La  fonction  do_use_fd()  va
       utiliser  le nouveau descripteur de fichier, jusqu'à ce que EAGAIN soit
       renvoyé par read(2) ou par write(2). Une application  fonctionnant  par
       transition d'état devrait, après réception d'EAGAIN, enregistrer l'état
       en cours, afin que l'appel suivant  de  do_use_fd()  continue  avec  le
       read(2) ou le write(2) où il s'est arrêté.

           #define MAX_EVENTS 10
           struct epoll_event ev, events[MAX_EVENTS];
           int listen_sock, conn_sock, nfds, epollfd;

           /* Set up listening socket, 'listen_sock' (socket(),
              bind(), listen()) */

           epollfd = epoll_create(10);
           if (epollfd == -1) {
               perror("epoll_create");
               exit(EXIT_FAILURE);
           }

           ev.events = EPOLLIN;
           ev.data.fd = listen_sock;
           if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
               perror("epoll_ctl: listen_sock");
               exit(EXIT_FAILURE);
           }

           for (;;) {
               nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
               if (nfds == -1) {
                   perror("epoll_pwait");
                   exit(EXIT_FAILURE);
               }

               for (n = 0; n < nfds; ++n) {
                   if (events[n].data.fd == listen_sock) {
                       conn_sock = accept(listen_sock,
                                       (struct sockaddr *) &local, &addrlen);
                       if (conn_sock == -1) {
                           perror("accept");
                           exit(EXIT_FAILURE);
                       }
                       setnonblocking(conn_sock);
                       ev.events = EPOLLIN | EPOLLET;
                       ev.data.fd = conn_sock;
                       if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
                                   &ev) == -1) {
                           perror("epoll_ctl: conn_sock");
                           exit(EXIT_FAILURE);
                       }
                   } 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/Réponses
       Q0  Quelle  est  la  clé  utilisée  pour distinguer les descripteurs de
           fichier enregistrés dans un ensemble epoll ?

       A0  La clé est une combinaison du numéro du descripteur de  fichier  et
           de la description du fichier ouvert (aussi connue comme « open file
           handle », la représentation interne au noyau d'un fichier ouvert).

       Q1  Que se passe-t-il si on enregistre deux fois le même descripteur de
           fichier dans une instance epoll ?

       A1  Vous  aurez  probablement  un  EEXIST.  Cependant  il  est possible
           d'ajouter un duplicat de  descripteur  (dup(2),  dup2(2),  fcntl(2)
           F_DUPFD)  sur  la même instance epoll. Ceci peut être une technique
           utile pour le filtrage d'événements, si les descripteurs  duplicats
           sont enregistrés avec un masque d'événements events différent.

       Q2  Deux  instances epoll peuvent-elles attendre le même descripteur de
           fichier ? Si oui, les événements seront-ils reportés sur  les  deux
           descripteurs de fichier epoll en même temps ?

       A2  Oui,  et  les  événements seront rapportés aux deux. Toutefois, une
           programmation soignée  est  nécessaire  pour  que  cela  soit  fait
           correctement.

       Q3  Peut-on   utiliser   le   descripteur   de   epoll   lui-même  avec
           poll/epoll/select ?

       A3  Oui. Si un  descripteur  de  fichier  epoll  a  des  événements  en
           attente, alors il indiquera qu'il est lisible.

       Q4  Que  se  passe-t-il  si on cherche à placer un descripteur de epoll
           dans son propre ensemble ?

       A4  L'appel à epoll_ctl(2) échouera  (EINVAL).  Toutefois  vous  pouvez
           ajouter un descripteur de epoll dans un autre ensemble epoll.

       Q5  Puis-je  envoyer  le descripteur de epoll à travers une socket UNIX
           vers un autre processus ?

       A5  Oui, mais il n'y a aucune raison de faire ça, puisque le  processus
           récepteur  n'aura  pas  de  copie  des  descripteurs  de fichier de
           l'ensemble epoll.

       Q6  Est-ce   que   la   fermeture   d'un   descripteur   le    supprime
           automatiquement de tous les ensembles epoll ?

       A6  Oui,  mais  prenez  note  des  points  suivants.  Un descripteur de
           fichier est une référence vers la description d'un  fichier  ouvert
           (consultez  open(2)).  À chaque fois qu'un descripteur est dupliqué
           avec dup(2), dup2(2),  fcntl(2)  F_DUPFD  ou  fork(2),  un  nouveau
           descripteur  de  fichier  qui  se réfère au même fichier ouvert est
           créé. Une description de fichier ouvert continue d'exister  jusqu'à
           ce  que  tous  les  descripteurs de fichier qui s'y réfèrent soient
           fermés. Un descripteur de fichier n'est retiré d'un ensemble  epoll
           qu'après  la  fermeture  de tous les descripteurs de fichier qui se
           réfèrent à la description de fichier ouvert sous-jacente (ou  avant
           si   le   descripteur   est   explicitement   retiré  en  utilisant
           epoll_ctl(2)  EPOLL_CTL_DEL).  Cela  signifie  que  même  après  la
           fermeture  d'un  descripteur  de  fichier  d'un ensemble epoll, des
           événements peuvent toujours être remontés pour  ce  descripteur  de
           fichier  si d'autres descripteurs de fichier, se référant à la même
           description de fichier sous-jacente, restent ouverts.

       Q7  Si plus d'un événement surviennent entre deux appels epoll_wait(2),
           sont-ils combinés ou rapportés séparément ?

       A7  Ils sont combinés.

       Q8  Est-ce  qu'une  opération sur un descripteur affecte les événements
           déjà collectés mais pas encore rapportés ?

       A8  Vous pouvez faire deux choses  sur  un  descripteur  existant.  Une
           suppression serait sans signification dans ce cas. Une modification
           revérifie les entrées-sorties disponibles.

       Q9  Dois-je lire/écrire  sans  cesse  un  descripteur  jusqu'à  obtenir
           EAGAIN avec l'attribut EPOLLET (comportement edge-triggered) ?

       A9  La  réception  d'un  événement  depuis  epoll_wait(2) suggère qu'un
           descripteur est prêt pour l'opération d'E/S désirée. Vous devez  le
           considérer  prêt  jusqu'à  ce  que la prochaine lecture ou écriture
           (non bloquante) remonte un EAGAIN. Quand  et  comment  utiliser  le
           descripteur dépend de vous.

           Pour les fichiers orientés paquet ou jeton (par exemple, une socket
           datagramme ou un terminal en mode canonique),  la  seule  façon  de
           détecter  la  fin  de l'espace d'entrée-sortie pour les lectures ou
           écritures est de continuer à lire ou écrire  jusqu'à  la  réception
           d'un EAGAIN.

           Pour  les  fichiers  orientés flux (par exemple, les tubes, FIFO ou
           sockets  en  mode  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. La même chose est vraie pour
           l'appel système write(2). (Évitez cette dernière technique si  vous
           ne   pouvez  garantir  que  le  descripteur  de  fichier  surveillé
           correspond toujours à un fichier de type flux)

   Erreurs possibles et moyens de les éviter
       o Famine (edge-triggered)

       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  problème  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 des
       descripteurs prêts.

       o Utilisation d'un cache d'événements...

       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
       avec close(2), 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

       L'API  epoll  a  été introduite dans le noyau Linux 2.5.44. La prise en
       charge par la glibc a été ajoutée dans la version 2.3.2.

CONFORMITÉ

       L'API  epoll  est  spécifique  à  Linux.   Certains   autres   systèmes
       fournissent  des  mécanismes  similaires.  Par exemple, FreeBSD propose
       kqueue et Solaris /dev/poll.

VOIR AUSSI

       epoll_create(2), epoll_create1(2), epoll_ctl(2), epoll_wait(2)

COLOPHON

       Cette page fait partie de  la  publication  3.32  du  projet  man-pages
       Linux.  Une description du projet et des instructions pour signaler des
       anomalies      peuvent      être       trouvées       à       l'adresse
       <URL:http://www.kernel.org/doc/man-pages/>.

TRADUCTION

       Depuis  2010,  cette  traduction est maintenue à l'aide de l'outil po4a
       <URL:http://po4a.alioth.debian.org/>   par   l'équipe   de   traduction
       francophone        au        sein        du       projet       perkamon
       <URL:http://perkamon.alioth.debian.org/>.

       Christophe Blaess  <URL:http://www.blaess.fr/christophe/>  (1996-2003),
       Alain   Portal   <URL:http://manpagesfr.free.fr/>  (2003-2006).  Julien
       Cristau et l'équipe francophone de traduction de Debian (2006-2009).

       Veuillez  signaler  toute  erreur   de   traduction   en   écrivant   à
       <debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
       paquet manpages-fr.

       Vous pouvez toujours avoir accès à la version anglaise de  ce  document
       en utilisant la commande « man -L C <section> <page_de_man> ».