eventfd(2) System Calls Manual eventfd(2) NOM eventfd - Creer un descripteur de fichier pour la notification d'evenements BIBLIOTHEQUE Bibliotheque C standard (libc, -lc) SYNOPSIS #include int eventfd(unsigned int initval, int flags); DESCRIPTION eventfd() creee un << objet eventfd >> qui peut etre utilise par les applications de l'espace utilisateur pour l'attente ou la notification d'un evenement et par le noyau pour notifier des applications de certains evenements. Les objets contiennent un compteur entier non signe sur 64 bits (uint64_t) qui est maintenu par le noyau. Ce compteur est initialise a la valeur specifiee par le parametre initval. Comme valeur de retour, eventfd() renvoie un nouveau descripteur de fichier qui peut etre utilise pour se referer a l'objet eventfd. Les valeurs suivantes peuvent etre 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 etre utile. EFD_NONBLOCK (depuis Linux 2.6.27) Placer l'attribut d'etat de fichier O_NONBLOCK sur la description du fichier ouvert referencee par le nouveau descripteur de fichier (consulter open(2)). Utiliser cet attribut economise des appels supplementaires a fcntl(2) pour obtenir le meme resultat. EFD_SEMAPHORE (depuis Linux 2.6.30) Fournir une semantique similaire aux semaphores pour les lectures sur le nouveau descripteur de fichier. Voir ci-dessous. Jusqu'a Linux 2.6.26, le parametre flags n'est pas utilise et doit valoir zero. Les operations suivantes peuvent etre effectuees sur le descripteur de fichier renvoye par eventfd() : read(2) Chaque read(2) qui reussit renvoie un entier sur 8 octets. read(2) echouera avec l'erreur EINVAL si la taille du tampon fourni est de moins de 8 octets. La valeur renvoyee par read(2) utilise l'ordre des octets de l'hote, c'est-a-dire l'ordre des octets natif pour les entiers sur la machine hote. La semantique de read(2) depend du fait que le compteur eventfd a actuellement une valeur non nulle, et que l'attribut EFD_SEMAPHORE etait specifie lors de la creation du descripteur de fichier eventfd : - Si EFD_SEMAPHORE n'etait pas specifie 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 a zero. - Si EFD_SEMAPHORE etait specifie 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 decrementee de 1. - Si le compteur eventfd est nul au moment de l'appel a read(2), l'appel bloquera jusqu'a ce que le compteur devienne non nul (auquel cas l'appel a read(2) sera traite comme decrit ci-dessus), ou echouera avec l'erreur EAGAIN si le descripteur de fichier est en mode non bloquant. write(2) Un appel a write(2) ajoute au compteur la valeur de l'entier sur 8 octets fourni dans le tampon. La valeur maximale qui peut etre stockee dans le compteur est le plus grand entier non signe sur 64 bits moins 1 (c'est-a-dire 0xfffffffffffffffe). Si l'addition resulte en un compteur qui depasserait la valeur maximale, le write(2) bloquera jusqu'a ce qu'un read(2) soit effectue sur le descripteur de fichier, ou echouera avec l'erreur EAGAIN si le descripteur de fichier est en mode non bloquant. Un write(2) echouera avec l'erreur EINVAL si la taille du tampon fourni est de moins de 8 octets ou si l'on essaie d'ecrire la valeur 0xffffffffffffffff. poll(2) select(2) (et similaire) Le descripteur de fichier prend en charge les poll(2) (et de facon analogue epoll(7)) et select(2) de la facon suivante : - Le descripteur de fichier est lisible (le parametre readfds de select(2) ; l'attribut POLLIN de poll(2)) si le compteur a une valeur superieure a 0. - Le descripteur de fichier est disponible en ecriture (le parametre writefds de select(2) ; l'attribut POLLOUT de poll(2)) s'il est possible d'ecrire une valeur d'au moins << 1 >> sans bloquer. - Si un depassement de la valeur du compteur a ete detectee, select(2) indique que le descripteur de fichier est disponible en lecture et en ecriture et poll(2) renvoie un evenement POLLERR. Comme indiquee ci-dessus, un write(2) ne peut jamais produire de depassement. Cependant, un depassement peut se produire si un << signal post >> eventfd de 2^64 a ete effectue par le sous-systeme KAIO (theoriquement possible, mais tres peut probable en pratique). Si un depassement survient, un read(2) renverra la valeur maximale d'un uint64_t (c'est-a-dire 0xffffffffffffffff). Le descripteur de fichier eventfd prend egalement 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 necessaire il doit etre ferme. Quand tous les descripteurs de fichier associes au meme objet eventfd ont ete fermes, les ressources pour cet objet sont liberees par le noyau. Une copie d'un descripteur de fichier cree par eventfd() est heritee par le fils produit par fork(2). Le duplicata du descripteur de fichier est associe au meme objet eventfd. Les descripteurs de fichier crees par eventfd() sont preserves au travers des executions par execve(2), sauf si l'attribut << close-on-exec >> est positionne. VALEUR RENVOYEE S'il reussit, 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 ete specifiee dans flags. EMFILE La limite du nombre de descripteurs de fichiers par processus a ete atteinte. ENFILE La limite du nombre total de fichiers ouverts pour le systeme entier a ete atteinte. ENODEV Impossible de monter (en interne) le peripherique anonyme d'inoeud. ENOMEM Il n'y a pas assez de memoire pour que le noyau cree le nouveau descripteur de fichier eventfd. ATTRIBUTS Pour une explication des termes utilises dans cette section, consulter attributes(7). +---------------------------------+--------------------------+---------+ |Interface | Attribut | Valeur | +---------------------------------+--------------------------+---------+ |eventfd() | Securite des threads | MT-Safe | +---------------------------------+--------------------------+---------+ VERSIONS Differences entre bibliotheque C et noyau Il y a deux appels systeme sous-jacent : eventfd() et eventfd2(), plus recent. Le premier appel systeme n'implemente pas le parametre flags. Le dernier appel systeme implemente les valeurs de flags decrite ci-dessus. La fonction enveloppe de la glibc utilisera eventfd2() quand il est present. Fonctionnalites supplementaires de la glibc La bibliotheque C de GNU definie un type supplementaire et deux fonctions qui tentent d'abstraire certains details pour la lecture ou l'ecriture 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 ecriture sur le descripteur de fichier eventfd, en renvoyant 0 si un nombre correct d'octets a ete transfere, ou -1 sinon. STANDARDS Linux, GNU. HISTORIQUE eventfd() Linux 2.6.22, glibc 2.8. eventfd2() Linux 2.6.27 (consultez les VERSIONS). Depuis la glibc 2.9, la fonction enveloppe pour eventfd() utilise l'appel systeme eventfd2() s'il est pris en charge par le noyau. NOTES Les applications peuvent utiliser un descripteur de fichier eventfd a la place d'un tube (consultez pipe(2)) a chaque fois qu'un tube est utilise pour signaler des evenements. 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 necessaire (alors que deux sont necessaires pour un tube). Quand un descripteur de fichier eventfd est utilise par le noyau, il peut fournir un pont entre l'espace utilisateur et l'espace noyau. Par exemple, les fonctionnalites comme KAIO (<< kernel AIO >>) pour signaler dans un descripteur de fichier que certaines operations sont finies. Un aspect important d'un descripteur de fichier eventfd est qu'il peut etre surveille comme n'importe quel descripteur de fichier avec select(2), poll(2) ou epoll(7). Ceci signifie qu'une application peut surveiller simultanement la disponibilite de fichiers << traditionnels >> et la disponibilite de mecanismes noyau qui gerent une interface eventfd. (Sans l'interface eventfd(), ces mecanismes ne pouvaient pas etre multiplexes avec select(2), poll(2) ou epoll(7)) La valeur actuelle d'un compteur eventfd peut etre visualisee avec l'entree du descripteur de fichier correspondant dans le repertoire /proc/pid/fdinfo du processus. Voir proc(5) pour plus de details. EXEMPLES Le programme suivant cree un descripteur de fichier eventfd puis cree un processus fils. Alors que le pere commence par s'endormir, le fils ecrit tous les entiers fournis sur la ligne de commande au descripteur de fichier eventfd. Quand le pere se reveille, il lit dans le descripteur de fichier eventfd. La session d'interpreteur suivant montre un echantillon d'execution du programme : $ ./a.out 1 2 4 7 14 Ecriture de l'enfant 1 dans efd Ecriture de l'enfant 2 dans efd Ecriture de l'enfant 4 dans efd Ecriture de l'enfant 7 dans efd Ecriture de l'enfant 14 dans efd L'enfant a fini la boucle d'ecriture Parent sur le point de lire Lecture du parent 28 (0x1c) depuis efd Source du programme #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int efd; uint64_t u; ssize_t s; if (argc < 2) { fprintf(stderr, "Utilisation : %s ...\n", argv[0]); exit(EXIT_FAILURE); } efd = eventfd(0, 0); if (efd == -1) err(EXIT_FAILURE, "eventfd"); switch (fork()) { case 0: for (size_t j = 1; j < argc; j++) { printf("Ecriture de l'enfant %s dans efd\en", argv[j]); u = strtoull(argv[j], NULL, 0);0 /* strtoull() autorise plusieurs bases bases */ s = write(efd, &u, sizeof(uint64_t)); if (s != sizeof(uint64_t)) err(EXIT_FAILURE, } printf("L'enfant a fini la boucle d'ecriture\n"); exit(EXIT_SUCCESS); default: sleep(2); printf( s = read(efd, &u, sizeof(uint64_t)); if (s != sizeof(uint64_t)) err(EXIT_FAILURE, "read"); printf("Lecture du parent %"PRIu64" (%#"PRIx64") depuis efd\n", u, u); exit(EXIT_SUCCESS); case -1: err(EXIT_FAILURE, "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) TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot , Cedric Boutillier , Frederic Hantrais et Jean-Philippe MENGUAL Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.8 2 mai 2024 eventfd(2)