eventfd

EVENTFD(2)                Manuel du programmeur Linux               EVENTFD(2)



NOM
       eventfd - Créer un descripteur de fichier pour la notification
       d'événements

SYNOPSIS
       #include <sys/eventfd.h>

       int eventfd(unsigned int initval, int flags);

DESCRIPTION
       eventfd() créée un « objet eventfd » qui peut être utilisé par
       les applications de l'espace utilisateur pour l'attente ou la
       notification d'un événement et par le noyau pour notifier des
       applications de certains événements. Les objets contiennent un
       compteur entier non signé sur 64 bits (uint64_t) qui est maintenu par
       le noyau. Ce compteur est initialisé à la valeur spécifiée par le
       paramètre initval.

       Les valeurs suivantes peuvent être incluses (avec un OU logique) dans
       flags pour changer le comportement de eventfd() :

       EFD_CLOEXEC (depuis Linux 2.6.27)
              Placer l'attribut « close-on-exec » (FD_CLOEXEC) sur le
              nouveau descripteur de fichier. Consultez la description de
              l'attribut O_CLOEXEC dans open(2) pour savoir pourquoi cela peut
              être utile.

       EFD_NONBLOCK (depuis Linux 2.6.27)
              Placer l'attribut d'état de fichier O_NONBLOCK sur le nouveau
              descripteur de fichier ouvert. Utiliser cet attribut économise
              des appels supplémentaires à fcntl(2) pour obtenir le même
              résultat.

       EFD_SEMAPHORE (depuis Linux 2.6.30)
              Fournir une sémantique similaire aux sémaphores pour les
              lectures sur le nouveau descripteur de fichier. Voir ci-dessous.

       Dans les versions de Linux jusqu'à la version 2.6.26, le paramètre
       flags n'est pas utilisé et doit valoir zéro.

       Comme valeur de retour, eventfd() renvoie un nouveau descripteur de
       fichier qui peut être utilisé pour se référer à l'objet eventfd.
       Les opérations suivantes peuvent être effectuées sur le descripteur
       de fichier :

       read(2)
              Chaque read(2) qui réussit renvoie un entier sur 8 octets.
              read(2) échouera avec l'erreur EINVAL si la taille du tampon
              fourni est de moins de 8 octets.

              La valeur renvoyée par read(2) utilise l'ordre des octets de
              l'hôte, c'est-à -dire l'ordre des octets natif pour les entiers
              sur la machine hôte.

              La sémantique de read(2) dépend du fait que le compteur
              eventfd a actuellement une valeur non nulle, et que l'attribut
              EFD_SEMAPHORE était spécifié lors de la création du
              descripteur de fichier eventfd :

              *  Si EFD_SEMAPHORE n'était pas spécifié et si le compteur
                 eventfd a une valeur non nulle, un read(2) renverra 8 octets
                 contenant cette valeur, et la valeur du compteur sera remise
                 à zéro.

              *  Si EFD_SEMAPHORE était spécifié et si le compteur eventfd
                 a une valeur non nulle, un read(2) renverra 8 octets
                 contenant la valeur 1, et la valeur du compteur sera
                 décrémentée de 1.

              *  Si le compteur eventfd est nul au moment de l'appel Ã
                 read(2), l'appel bloquera jusqu'Ã  ce que le compteur
                 devienne non nul (auquel cas l'appel à read(2) sera traité
                 comme décrit ci-dessus), ou échouera avec l'erreur EAGAIN
                 si le descripteur de fichier est en mode non bloquant.

       write(2)
              Un appel à write(2) ajoute au compteur la valeur de l'entier
              sur 8 octets fourni dans le tampon. La valeur maximale qui peut
              être stockée dans le compteur est le plus grand entier non
              signé sur 64 bits moins 1 (c'est-à -dire 0xfffffffffffffffe).
              Si l'addition résulte en un compteur qui dépasserait la valeur
              maximale, le write(2) bloquera jusqu'Ã  ce qu'un read(2) soit
              effectué sur le descripteur de fichier, ou échouera avec
              l'erreur EAGAIN si le descripteur de fichier est en mode non
              bloquant.

              Un write(2) échouera avec l'erreur EINVAL si la taille du
              tampon fourni est de moins de 8 octets ou si l'on essaie
              d'écrire la valeur 0xffffffffffffffff.

       poll(2), select(2) (et similaires)
              Le descripteur de fichier prend en charge les poll(2) (et de
              façon analogue epoll(7)) et select(2) de la façon suivante :

              *  Le descripteur de fichier est lisible (le paramètre readfds
                 de select(2) ; l'attribut POLLIN de poll(2)) si le compteur a
                 une valeur supérieure à 0.

              *  Le descripteur de fichier est disponible en écriture (le
                 paramètre writefds de select(2) ; l'attribut POLLOUT de
                 poll(2)) s'il est possible d'écrire une valeur d'au moins
                 « 1 » sans bloquer.

              *  Si un dépassement de la valeur du compteur a été
                 détectée, select(2) indique que le descripteur de fichier
                 est disponible en lecture et en écriture et poll(2) renvoie
                 un événement POLLERR. Comme indiquée ci-dessus, un
                 write(2) ne peut jamais produire de dépassement. Cependant,
                 un dépassement peut se produire si un « signal post »
                 eventfd de 2^64 a été effectué par le sous-système KAIO
                 (théoriquement possible, mais très peut probable en
                 pratique). Si un dépassement survient, un read(2) renverra
                 la valeur maximale d'un uint64_t (c'est-Ã -dire
                 0xffffffffffffffff).

              Le descripteur de fichier eventfd prend également en charge les
              autres interfaces de multiplexage de descripteurs de fichier :
              pselect(2) et ppoll(2).

       close(2)
              Quand le descripteur de fichier n'est plus nécessaire il doit
              être fermé. Quand tous les descripteurs de fichier associés
              au même objet eventfd ont été fermés, les ressources pour
              cet objet sont libérées par le noyau.

       Une copie d'un descripteur de fichier créé par eventfd() est
       héritée par le fils produit par fork(2). Le duplicata du descripteur
       de fichier est associé au même objet eventfd. Les descripteurs de
       fichier créés par eventfd() sont préservés au travers des
       exécutions par execve(2), sauf si l'attribut « close‐on‐exec » est
       positionné.

VALEUR RENVOYÃE
       S'il réussit, eventfd() renvoie un nouveau descripteur de fichier
       eventfd. En cas d'erreur, il renvoie -1 et remplit errno avec la valeur
       d'erreur.

ERREURS
       EINVAL Une valeur non prise en compte a été spécifiée dans flags.

       EMFILE La limite des descripteurs ouverts pour le processus a été
              atteinte.

       ENFILE La limite du nombre total de fichiers ouverts sur le système a
              été atteinte.

       ENODEV Impossible de monter (en interne) le périphérique anonyme
              d'inÅud.

       ENOMEM Il n'y a pas assez de mémoire pour que le noyau crée le
              nouveau descripteur de fichier eventfd.

VERSIONS
       eventfd() est disponible sous Linux depuis le noyau 2.6.22. Le support
       fonctionnel est fourni par la glibc depuis la version 2.8. L'appel
       système eventfd2() (consultez les NOTES) est disponible sous Linux
       depuis le noyau 2.6.27. Depuis la version 2.9, la fonction enveloppe de
       la glibc pour eventfd() utilise l'appel système eventfd2() s'il est
       pris en charge par le noyau.

CONFORMITÃ
       eventfd() et eventfd2() sont spécifiques à Linux.

NOTES
       Les applications peuvent utiliser un descripteur de fichier eventfd Ã
       la place d'un tube (consultez pipe(2)) Ã  chaque fois qu'un tube est
       utilisé pour signaler des événements. La surcharge du noyau pour un
       descripteur de fichier est bien plus faible que pour un tube. De plus
       un seul descripteur de fichier est nécessaire (alors que deux sont
       nécessaires pour un tube).

       Quand un descripteur de fichier eventfd est utilisé par le noyau, il
       peut fournir un pont entre l'espace utilisateur et l'espace noyau. Par
       exemple, les fonctionnalités comme KAIO (« kernel AIO ») pour
       signaler dans un descripteur de fichier que certaines opérations sont
       finies.

       Un aspect important d'un descripteur de fichier eventfd est qu'il peut
       être surveillé comme n'importe quel descripteur de fichier avec
       select(2), poll(2) ou epoll(7). Ceci signifie qu'une application peut
       surveiller simultanément la disponibilité de fichiers
       « traditionnels » et la disponibilité de mécanismes noyau qui
       gèrent une interface eventfd. (Sans l'interface eventfd(), ces
       mécanismes ne pouvaient pas être multiplexés avec select(2), poll(2)
       ou epoll(7))

   Appels système Linux sous-jacents
       Il y a deux appels système sous-jacent : eventfd() et eventfd2(), plus
       récent. Le premier appel système n'implémente pas le paramètre
       flags. Le dernier appel système implémente les valeurs de flags
       décrite ci-dessus. La fonction enveloppe de la glibc utilisera
       eventfd2() quand il est présent.

   Fonctionnalités supplémentaires de la glibc
       La bibliothèque C de GNU définie un type supplémentaire et deux
       fonctions qui tentent d'abstraire certains détails pour la lecture ou
       l'écriture avec des descripteurs de fichier eventfd :

           typedef uint64_t eventfd_t;

           int eventfd_read(int fd, eventfd_t *value);
           int eventfd_write(int fd, eventfd_t value);

       Les fonctions effectuent des actions de lecture ou écriture sur le
       descripteur de fichier eventfd, en renvoyant 0 si un nombre correct
       d'octets a été transféré, ou -1 sinon.

EXEMPLE
       Le programme suivant crée un descripteur de fichier eventfd puis crée
       un processus fils. Alors que le père commence par s'endormir, le fils
       écrit tous les entiers fournis sur la ligne de commande au descripteur
       de fichier eventfd. Quand le père se réveille, il lit dans le
       descripteur de fichier eventfd.

       La session shell suivante montre un exemple d'exécution du programme :

           $ ./a.out 1 2 4 7 14
           Child writing 1 to efd
           Child writing 2 to efd
           Child writing 4 to efd
           Child writing 7 to efd
           Child writing 14 to efd
           Child completed write loop
           Parent about to read
           Parent read 28 (0x1c) from efd

   Source du programme

       #include <sys/eventfd.h>
       #include <unistd.h>
       #include <stdlib.h>
       #include <stdio.h>
       #include <stdint.h>             /* Definition de uint64_t */

       #define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

       int
       main(int argc, char *argv[])
       {
           int efd, j;
           uint64_t u;
           ssize_t s;

           if (argc < 2) {
               fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           efd = eventfd(0, 0);
           if (efd == -1)
               handle_error("eventfd");

           switch (fork()) {
           case 0:
               for (j = 1; j < argc; j++) {
                   printf("Child writing %s to efd\n", argv[j]);
                   u = strtoull(argv[j], NULL, 0);
                           /* strtoull() allows various bases */
                   s = write(efd, &u, sizeof(uint64_t));
                   if (s != sizeof(uint64_t))
                       handle_error("write");
               }
               printf("Child completed write loop\n");

               exit(EXIT_SUCCESS);

           default:
               sleep(2);

               printf("Parent about to read\n");
               s = read(efd, &u, sizeof(uint64_t));
               if (s != sizeof(uint64_t))
                   handle_error("read");
               printf("Parent read %llu (0x%llx) from efd\n",
                       (unsigned long long) u, (unsigned long long) u);
               exit(EXIT_SUCCESS);

           case -1:
               handle_error("fork");
           }
       }

VOIR AUSSI
       futex(2), pipe(2), poll(2), read(2), select(2), signalfd(2),
       timerfd_create(2), write(2), epoll(7), sem_overview(7)

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

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

       Julien Cristau et l'équipe francophone de traduction de
       Debian (2006-2009).

       Veuillez signaler toute erreur de traduction en écrivant Ã
       <perkamon-fr@traduc.org>.

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



Linux                           8 juillet 2014                      EVENTFD(2)