.\" -*- coding: UTF-8 -*- .\" Copyright (C) 2003 Davide Libenzi .\" .\" %%%LICENSE_START(GPLv2+_SW_3_PARA) .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public .\" License along with this manual; if not, see .\" . .\" %%%LICENSE_END .\" .\" Davide Libenzi .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH EPOLL 7 "6 mars 2019" Linux "Manuel du programmeur Linux" .SH NOM epoll – Notifications d'événements d'entrées et sorties .SH SYNOPSIS \fB#include \fP .SH DESCRIPTION L'interface de programmation (API) \fBepoll\fP réalise une tâche similaire à \fBpoll\fP(2)\ : surveiller plusieurs descripteurs de fichier pour voir si des E/S y sont possibles. L'API \fBepoll\fP peut être déclenchée par changement de niveau ou par changement d'état et s'adapte bien à un grand nombre de descripteurs surveillés. .PP Le concept central de l’API \fBepoll\fP est l’\fIinstance\fP d’\fBepoll\fP, une structure interne au noyau qui, du point de vue espace utilisateur, peut être considérée comme un conteneur pour deux listes\ : .IP \(bu 2 La liste \fIinterest\fP (parfois appelée l’ensemble \fBepoll\fP)\ : l’ensemble des descripteurs de fichier que le processus a enregistrés comme intéressants à surveiller. .IP \(bu La liste \fIready\fP\ : l’ensemble des descripteurs de fichier prêts (ready) pour des E/S. Cette liste est un sous\-ensemble de (plus précisément, un ensemble de références de) descripteurs de fichier de la liste \fIinterest\fP. La liste \fIready\fP est alimentée dynamiquement par le noyau selon le résultat des activités d’E/S de ces descripteurs de fichier. .PP Les appels système suivants sont fournis pour créer et gérer une instance d’\fBepoll\fP\ : .IP \(bu 2 \fBepoll_create\fP(2) crée une instance d’\fBepoll\fP et renvoie un descripteur de fichier référençant cette instance. La version plus récente d'\fBepoll_create1\fP(2) étend les fonctionnalités d'\fBepoll_create\fP(2). .IP \(bu L'intérêt pour des descripteurs de fichier particuliers est ensuite enregistré avec \fBepoll_ctl\fP(2), qui ajoute les articles dans la liste \fIinterest\fP de l’instance d’\fBepoll\fP. .IP \(bu .\" \fBepoll_wait\fP(2) attend les événements d'E/S, en bloquant le thread appelant si aucun événement n'est actuellement disponible. Cet appel système peut être considéré comme recherchant des articles dans la liste \fIready\fP de l’instance d’\fBepoll\fP. .SS "Détection par changement de niveau ou d’état" L'interface de distribution d'événements d’\fBepoll\fP est capable de se comporter en détection de changement de niveau (Level Triggered —\ LT) ou d’état (Edge Triggered —\ ET). La différence entre ces deux mécanismes est décrite ci\-dessous. Supposons que le scénario suivant se produise\ : .IP 1. 3 Le descripteur de fichier qui représente le côté lecture d'un tube (\fIrfd\fP) est enregistré dans l'instance d’\fBepoll\fP. .IP 2. Une écriture dans le tube envoie 2\ Ko de données du côté écriture du tube. .IP 3. Un appel à \fBepoll_wait\fP(2) est effectué et renvoie \fIrfd\fP comme descripteur de fichier prêt. .IP 4. Un lecteur du tube lit 1\ Ko de données depuis \fIrfd\fP. .IP 5. Un appel d’\fBepoll_wait\fP(2) est effectué. .PP Si le descripteur \fIrfd\fP a été ajouté à l'ensemble \fBepoll\fP en utilisant l'attribut \fBEPOLLET\fP (détection de changement d'état), l'appel \fBepoll_wait\fP(2), réalisé à l'étape\ \fB5\fP, va probablement bloquer bien qu'il y ait des données toujours présentes dans le tampon d'entrée du fichier tandis que 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 détectés par changement d’état délivre les événements seulement lorsque des événements surviennent dans le descripteur de fichier supervisé. Ainsi, à l'étape\ \fB5\fP, 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 \fIrfd\fP sera déclenché à cause de l'écriture à l'étape\ \fB2\fP et l'événement est consommé dans l’étape\ \fB3\fP. Comme l'opération de lecture de l'étape\ \fB4\fP ne consomme pas toutes les données du tampon, l'appel à \fBepoll_wait\fP(2) effectué à l'étape\ \fB5\fP peut verrouiller indéfiniment. .PP Une application qui emploie l'attribut \fBEPOLLET\fP de la fonction \fBepoll\fP devrait toujours utiliser des descripteurs non bloquants pour éviter qu'une lecture ou une écriture affame une tâche qui gère plusieurs descripteurs de fichier. L'utilisation préconisée d'\fBepoll\fP comme interface en détection par changement d’état (\fBEPOLLET\fP) est la suivante\ : .IP a) 3 avec des descripteurs non bloquants\ ; .IP b) en attente d’évènement seulement après qu'un \fBread\fP(2) ou un \fBwrite\fP(2) ait renvoyé \fBEAGAIN\fP. .PP En revanche, lorsqu'il est utilisé avec l'interface en détection par changement de niveau (par défaut si \fBEPOLLET\fP n'est pas spécifié), \fBepoll\fP est une alternative plus rapide à \fBpoll\fP(2) et peut être employé à chaque fois que ce dernier est utilisé, car il utilise la même sémantique. .PP Puisque même dans un \fBepoll\fP de type détection le changement d'état, 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 \fBEPOLLONESHOT\fP, faire désactiver par \fBepoll\fP le descripteur de fichier associé après la réception d'un événement avec \fBepoll_wait\fP(2). Lorsque l'attribut \fBEPOLLONESHOT\fP est spécifié, il est de la responsabilité de l'appelant de réarmer le descripteur en utilisant \fBepoll_ctl\fP(2) avec \fBEPOLL_CTL_MOD\fP. .PP .\" Si plusieurs threads (ou processus si les processus enfant ont hérité du descripteur de fichier d’\fBepoll\fP à travers \fBfork\fP(2)) sont bloqués dans \fBepoll_wait\fP(2) en attente du même descripteur de fichier d’\fBepoll\fP et qu’un descripteur de fichier dans la liste \fIinterest\fP, qui est marqué pour une notification par détection de changement d'état (\fBEPOLLET\fP), devienne prêt, seul un des threads (ou processus) est réveillé de \fBepoll_wait\fP(2). Cela fournit une optimisation utile pour éviter la bousculade de réveils (thundering herd) dans certain scénarios. .SS "Interaction avec autosleep" Si le système est en mode \fBautosleep\fP à l’aide de \fI/sys/power/autosleep\fP et qu’un événement survient et sort le périphérique de sa veille, le pilote de périphérique ne gardera le périphérique actif que jusqu’à la mise en file d’attente de l’événement. Pour garder le périphérique actif jusqu’au traitement de l’événement, l’attribut \fBEPOLLWAKEUP\fP d’\fBepoll_ctl\fP(2) doit être utilisé. .PP Quand l’attribut \fBEPOLLWAKEUP\fP est défini dans le champ \fBevents\fP pour une \fIstruct epoll_event\fP, le système sera gardé actif à partir du moment où l’événement est mis en file d’attente, à l’aide de l’appel \fBepoll_wait\fP(2) qui renvoie l’événement jusqu’à l’appel \fBepoll_wait\fP(2) suivant. Si l’événement doit garder le système actif au delà de ce moment, alors un \fIwake_lock\fP séparé devrait être pris avant le second appel à \fBepoll_wait\fP(2). .SS "Interfaces /proc" .\" Following was added in 2.6.28, but them removed in 2.6.29 .\" .TP .\" .IR /proc/sys/fs/epoll/max_user_instances " (since Linux 2.6.28)" .\" This specifies an upper limit on the number of epoll instances .\" that can be created per real user ID. Les interfaces suivantes peuvent être utilisées pour limiter la quantité de mémoire du noyau utilisée par \fBepoll\fP\ : .TP \fI/proc/sys/fs/epoll/max_user_watches\fP (depuis Linux\ 2.6.28) .\" 2.6.29 (in 2.6.28, the default was 1/32 of lowmem) Cela définit une limite au nombre total de descripteurs de fichiers qu'un utilisateur peut enregistrer au travers de toutes les instances d’\fBepoll\fP 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 \fImax_user_watches\fP est de 1/25 (4%) de la mémoire basse disponible, divisé par le coût d'allocation en octets. .SS "Exemple d'utilisation" Tandis que l'utilisation d’\fBepoll\fP avec un déclenchement par changement de niveau correspond à la même sémantique que \fBpoll\fP(2), le déclenchement par changement d'état nécessite plus de clarification pour éviter des décrochages dans la boucle d’évènements de l’application. Dans cet exemple, l’écouteur emploie un socket non bloquant sur lequel \fBlisten\fP(2) a été appelé. La fonction \fIdo_use_fd()\fP va utiliser le nouveau descripteur de fichier jusqu'à ce qu’\fBEAGAIN\fP soit renvoyé par \fBread\fP(2) ou par \fBwrite\fP(2). Une application d’automate fini piloté par les évènements devrait, après réception d'\fBEAGAIN\fP, enregistrer l'état en cours, afin que lors de l’appel suivant à \fIdo_use_fd()\fP, elle continue avec le \fBread\fP(2) ou le \fBwrite\fP(2) là où elle s'est arrêtée. .PP .in +4n .EX #define MAX_EVENTS 10 struct epoll_event ev, events[MAX_EVENTS]; int listen_sock, conn_sock, nfds, epollfd; /* Code pour régler le socket d’écoute, \(aqlisten_sock\(aq, (socket(), bind(), listen()) omitted */ epollfd = epoll_create1(0); if (epollfd == \-1) { perror("epoll_create1"); 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_wait"); exit(EXIT_FAILURE); } for (n = 0; n < nfds; ++n) { if (events[n].data.fd == listen_sock) { conn_sock = accept(listen_sock, (struct sockaddr *) &addr, &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); } } } .EE .in .PP 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 d’\fBepoll\fP (\fBEPOLL_CTL_ADD\fP) après, en spécifiant (\fBEPOLLIN\fP|\fBEPOLLOUT\fP). Cela évite de basculer sans cesse entre \fBEPOLLIN\fP et \fBEPOLLOUT\fP lors des appels \fBepoll_ctl\fP(2) avec \fBEPOLL_CTL_MOD\fP. .SS Questions/Réponses .IP 0. 4 Quelle est la clé utilisée pour distinguer les descripteurs de fichier enregistrés dans une liste \fIinterest\fP\ ? .IP 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). .IP 1. Que se passe\-t\-il si on enregistre deux fois le même descripteur de fichier dans une instance d’\fBepoll\fP\ ? .IP .\" But a file descriptor duplicated by fork(2) can't be added to the .\" set, because the [file *, fd] pair is already in the epoll set. .\" That is a somewhat ugly inconsistency. On the one hand, a child process .\" cannot add the duplicate file descriptor to the epoll set. (In every .\" other case that I can think of, file descriptors duplicated by fork have .\" similar semantics to file descriptors duplicated by dup() and friends.) On .\" the other hand, the very fact that the child has a duplicate of the .\" file descriptor means that even if the parent closes its file descriptor, .\" then epoll_wait() in the parent will continue to receive notifications for .\" that file descriptor because of the duplicated file descriptor in the child. .\" .\" See http://thread.gmane.org/gmane.linux.kernel/596462/ .\" "epoll design problems with common fork/exec patterns" .\" .\" mtk, Feb 2008 Vous aurez probablement un \fBEEXIST\fP. Cependant il est possible d'ajouter un duplicata de descripteur (\fBdup\fP(2), \fBdup2\fP(2), \fBF_DUPFD\fP de \fBfcntl\fP(2)) sur la même instance d’\fBepoll\fP. Cela peut être une technique utile pour le filtrage d'événements, si les descripteurs dupliqués sont enregistrés avec des masques \fIevents\fP différents. .IP 2. Deux instances d’\fBepoll\fP peuvent\-elles attendre le même descripteur de fichier\ ? Si oui, les événements seront\-ils reportés sur les deux descripteurs de fichier d’\fBepoll\fP\ ? .IP Oui, et les événements seront rapportés aux deux. Toutefois, une programmation soignée est nécessaire pour que cela soit fait correctement. .IP 3. Est\-ce que le descripteur d’\fBepoll\fP lui\-même est sujet à poll/epoll/select\ ? .IP Oui. Si un descripteur de fichier d’\fBepoll\fP a des événements en attente, alors il indiquera qu'il est lisible. .IP 4. Que se passe\-t\-il si on cherche à placer un descripteur d’\fBepoll\fP dans son propre ensemble de descripteurs de fichier \ ? .IP L'appel \fBepoll_ctl\fP(2) échouera (\fBEINVAL\fP). Toutefois vous pouvez ajouter un descripteur d’\fBepoll\fP dans un autre ensemble de descripteurs de fichier d’\fBepoll\fP. .IP 5. Puis\-je envoyer le descripteur d’\fBepoll\fP à travers un socket UNIX vers un autre processus\ ? .IP 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 la liste \fIinterest\fP. .IP 6. Est\-ce que la fermeture d'un descripteur le supprime automatiquement de toutes les listes \fIinterest\fP d’\fBepoll\fP\ ? .IP Oui, mais prenez note des points suivants. Un descripteur de fichier est une référence vers la description d'un fichier ouvert (consultez \fBopen\fP(2)). À chaque fois qu'un descripteur est dupliqué avec \fBdup\fP(2), \fBdup2\fP(2), \fBF_DUPFD\fP de \fBfcntl\fP(2) ou \fBfork\fP(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. .IP Un descripteur de fichier n'est retiré d'une liste \fIinterest\fP qu'après la fermeture de tous les descripteurs de fichier qui se réfèrent à la description de fichier ouvert sous\-jacente. Cela signifie que même après la fermeture d'un descripteur de fichier faisant partie de cette liste, des événements peuvent toujours être rapporté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. Pour empêcher cela, le descripteur de fichier doit être explicitement supprimé de la liste (en utilisant \fBepoll_ctl\fP(2) \fBEPOLL_CTL_DEL\fP) avant qu’il ne soit dupliqué. Autrement, l’application doit assurer que tous les descripteurs soient fermés (ce qui peut être difficile si les descripteurs ont été dupliqués en dehors du cadre par des fonctions de bibliothèque qui utilisent \fBdup\fP(2) ou \fBfork\fP(2)) .IP 7. Si plus d'un événement surviennent entre deux appels \fBepoll_wait\fP(2), sont\-ils combinés ou rapportés séparément\ ? .IP Ils sont combinés. .IP 8. Est\-ce qu'une opération sur un descripteur affecte les événements déjà collectés mais pas encore rapportés\ ? .IP Vous pouvez faire deux choses sur un descripteur existant. Une suppression serait sans effet dans ce cas. Une modification revérifie les entrées et sorties disponibles. .IP 9. Dois\-je lire/écrire sans cesse un descripteur jusqu'à obtenir \fBEAGAIN\fP si l'attribut \fBEPOLLET\fP est utilisé (comportement par détection de changement d'état)\ ? .IP La réception d'un événement depuis \fBepoll_wait\fP(2) suggère qu'un descripteur est prêt pour l'opération d'E/S désirée. Il doit être considéré comme prêt jusqu'à ce que la prochaine lecture ou écriture (non bloquante) remonte un \fBEAGAIN\fP. Quand et comment utiliser le descripteur dépend de vous. .IP Pour les fichiers orientés paquet ou jeton (par exemple, un socket datagramme ou un terminal en mode canonique), la seule façon de détecter la fin de l'espace d'entrée et sortie pour les lectures ou écritures est de continuer à lire ou écrire jusqu'à la réception d'un \fBEAGAIN\fP. .IP Pour les fichiers orientés flux (par exemple, les tubes, FIFO ou sockets en mode flux), la disponibilité des entrées et sorties peut aussi être détectée en vérifiant la quantité de données lues ou écrites sur le descripteur. Par exemple, si vous appelez \fBread\fP(2) en demandant la lecture d'une certaine quantité de données et que \fBread\fP(2) en renvoie moins, vous pouvez être sûr d'avoir consommé tout le tampon d'entrée pour le descripteur. La même chose est vraie pour l'appel système \fBwrite\fP(2) (évitez cette dernière technique si vous ne pouvez pas garantir que le descripteur de fichier surveillé corresponde toujours à un fichier de type flux). .SS "Erreurs possibles et moyens de les éviter" .TP \fBFamine (détection par changement d'état)\fP .PP S'il y a un gros volume d’espace d’E/S, il est possible qu'en essayant de les traiter, d'autres fichiers ne soient pas pris en compte provoquant une famine. Ce problème n'est pas spécifique à \fBepoll\fP. .PP La solution est de maintenir une liste de descripteurs prêts et de marquer le descripteur de fichier prêt dans leur structure associée, permettant à l'application de savoir quels fichiers traiter mais toujours en tourniquet englobant tous les fichiers prêts. Cela permet aussi d'ignorer les événements ultérieurs sur des descripteurs prêts. .TP \fBEn cas d’utilisation d'un cache d'événements...\fP .PP Si vous utilisez un cache d'événements, ou stockez tous les descripteurs renvoyés par \fBepoll_wait\fP(2), alors assurez\-vous de disposer d'un moyen de marquer dynamiquement leurs fermetures (c’est\-à\-dire causées par un traitement d’événement précédent). Supposons que vous recevez 100\ événements d’\fBepoll_wait\fP(2) et que l'événement\ 47 implique de fermer l’évènement\ 13. Si vous supprimez la structure et utilisez \fBclose\fP(2) pour le descripteur de fichier pour l’évènement\ 13, alors votre cache peut encore contenir des événements pour ce descripteur, posant alors des problèmes de confusion. .PP Une solution est d'invoquer, pendant le traitement de l'événement\ 47, \fBepoll_ctl\fP(\fBEPOLL_CTL_DEL\fP) pour supprimer le descripteur\ 13, le fermer avec \fBclose\fP(2), puis marquer sa structure associée comme supprimée et la lier à une liste de nettoyage. 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. .SH VERSIONS .\" Its interface should be finalized in Linux kernel 2.5.66. L'API \fBepoll\fP a été introduite dans le noyau Linux\ 2.5.44. Sa prise en charge par la glibc est ajoutée dans la version\ 2.3.2. .SH CONFORMITÉ L'API \fBepoll\fP est spécifique à Linux. Certains autres systèmes fournissent des mécanismes similaires. Par exemple, FreeBSD propose \fIkqueue\fP et Solaris \fI/dev/poll\fP. .SH NOTES L’ensemble des descripteurs de fichier qui sont supervisés par un descripteur de fichier d’\fBepoll\fP peut être visualisé à l’aide de l’entrée pour le descripteur de fichier d’\fBepoll\fP dans le répertoire \fI/proc/[pid]/fdinfo\fP du processus. Consultez \fBproc\fP(5) pour plus de détails. .PP L’opération \fB\fBKCMP_EPOLL_TFD\fP de \fBkcmp\fP(2)\fP peut être utilisée pour tester si un descripteur de fichier est présent dans une instance d’\fBepoll\fP. .SH "VOIR AUSSI" \fBepoll_create\fP(2), \fBepoll_create1\fP(2), \fBepoll_ctl\fP(2), \fBepoll_wait\fP(2), \fBpoll\fP(2), \fBselect\fP(2) .SH COLOPHON Cette page fait partie de la publication\ 5.10 du projet \fIman\-pages\fP 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/. .PP .SH TRADUCTION La traduction française de cette page de manuel a été créée par Christophe Blaess , Stéphan Rafin , Thierry Vignaud , François Micaux, Alain Portal , Jean-Philippe Guérard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas François , Florentin Duneau , Simon Paillard , Denis Barbier , David Prévot et Jean-Paul Guillonneau . .PP Cette traduction est une documentation libre ; veuillez vous reporter à la .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3 .UE concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE. .PP Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à .MT debian-l10n-french@lists.debian.org .ME .