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.
Comme valeur de retour, eventfd() renvoie un nouveau descripteur de fichier qui peut être utilisé pour se référer à l’objet eventfd.
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 la description du fichier ouvert référencée par le nouveau descripteur de fichier (consulter open(2)). 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.
Les
opérations suivantes peuvent être
effectuées sur le descripteur de fichier
renvoyé par eventfd() : 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. 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 similaire) 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). 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é. 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. EINVAL Une valeur non prise en compte a
été spécifiée dans
flags. EMFILE La limite du nombre de descripteurs de fichiers par
processus a été atteinte. ENFILE La limite du nombre total de fichiers ouverts pour le
système entier 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. 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. Pour une
explication des termes utilisés dans cette section,
consulter attributes(7). eventfd()
et eventfd2() sont spécifiques à
Linux. 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)) La valeur
actuelle d’un compteur eventfd peut être
visualisée avec l’entrée du descripteur
de fichier correspondant dans le répertoire
/proc/[pid]/fdinfo du processus. Voir proc(5)
pour plus de détails. différences
entre bibliothèque C et noyau Fonctionnalités
supplémentaires de la glibc 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. 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 Source du
programme futex(2),
pipe(2), poll(2), read(2),
select(2), signalfd(2),
timerfd_create(2), write(2), epoll(7),
sem_overview(7)
Cette page fait
partie de la publication 5.07 du projet
man-pages Linux. Une description du projet et des
instructions pour signaler des anomalies et la
dernière version de cette page, peuvent être
trouvées à l’adresse
https://www.kernel.org/doc/man-pages/. La traduction
française de cette page de manuel a été
créée par Christophe Blaess
<https://www.blaess.fr/christophe/>, Stéphan
Rafin <stephan.rafin [AT] laposte.net>, Thierry Vignaud
<tvignaud [AT] mandriva.com>, François Micaux, Alain
Portal <aportal [AT] univ-montp2.fr>, Jean-Philippe
Guérard <fevrier [AT] tigreraye.org>, Jean-Luc
Coulon (f5ibh) <jean-luc.coulon [AT] wanadoo.fr>, Julien
Cristau <jcristau [AT] debian.org>, Thomas Huriaux
<thomas.huriaux [AT] gmail.com>, Nicolas François
<nicolas.francois [AT] centraliens.net>, Florentin Duneau
<fduneau [AT] gmail.com>, Simon Paillard
<simon.paillard [AT] resel.fr>, Denis Barbier
<barbier [AT] debian.org>, David Prévot
<david [AT] tilapin.org>, Cédric Boutillier
<cedric.boutillier [AT] gmail.com>, Frédéric
Hantrais <fhantrais [AT] gmail.com> et Jean-Philippe
MENGUAL <jpmengual [AT] debian.org> Cette
traduction est une documentation libre ; veuillez vous
reporter à la GNU General Public License
version 3 concernant les conditions de copie et de
distribution. Il n’y a aucune RESPONSABILITÉ
LÉGALE. Si vous
découvrez un bogue dans la traduction de cette page
de manuel, veuillez envoyer un message à
<debian-l10n-french [AT] lists.org>.
read(2)
VALEUR RENVOYÉE
ERREURS
VERSIONS
ATTRIBUTS
CONFORMITÉ
NOTES
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.
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);
EXEMPLES
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
#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
COLOPHON
TRADUCTION