timerfd_create(2) | System Calls Manual | timerfd_create(2) |
timerfd_create, timerfd_settime, timerfd_gettime - Minuteries qui informent par l'intermédiaire de descripteurs de fichier
Bibliothèque C standard (libc, -lc)
#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *_Nullable old_value); int timerfd_gettime(int fd, struct itimerspec *curr_value);
Ces appels système créent et opèrent sur une minuterie qui fournit des notifications d'expiration par un descripteur de fichier. Ils fournissent une alternative à setitimer(2) ou timer_create(2) avec l'avantage que le descripteur de fichier peut être surveillé avec select(2), poll(2) ou epoll(7).
L'utilisation de ces trois appels système est analogue à l'utilisation de timer_create(2), timer_settime(2) et timer_gettime(2). (Il n'y a pas d'équivalent à timer_getoverrun(2) puisque cette fonctionnalité est fournie par read(2), comme décrit ci-dessous)
timerfd_create() crée un nouvel objet minuterie et renvoie un descripteur de fichier qui se réfère à cette minuterie. Le paramètre clockid indique l'horloge utilisée pour marquer la progression de la minuterie qui doit être une des suivantes :
Consultez clock_getres(2) pour quelques détails supplémentaires sur les horloges mentionnées.
La valeur actuelle de chacune de ces horloges peut être obtenue avec clock_gettime(2).
À partir de Linux 2.6.27, les valeurs suivantes peuvent être incluses avec un OU binaire dans flags pour changer le comportement de timerfd_create() :
Dans les versions de Linux jusqu'à la version 2.6.26 incluse, flags doit être nul.
timerfd_settime() arme (démarre) ou désarme (stoppe) la minuterie à laquelle se réfère le descripteur de fichier fd.
Le paramètre new_value spécifie l'expiration initiale et l'intervalle de la minuterie. La structure itimerspec utilisée pour ce paramètre est décrite dans itimerspec(3type) :
new_value.it_value spécifie l'expiration initiale de la minuterie, en secondes et nanosecondes. Une valeur non nulle dans un des champs de new_value.it_value arme la minuterie. La minuterie est désarmée si les deux champs de new_value.it_value sont mis à zéro.
Une valeur non nulle dans un des champs de new_value.it_interval configure la période, en secondes et nanosecondes, pour une expiration répétitive après l'expiration initiale. Si les deux champs de new_value.it_interval sont nuls, la minuterie expirera qu'une seule fois, dont l'heure est spécifiée dans new_value.it_value.
Par défaut, l'heure d'expiration initiale spécifiée dans new_value est interprétée de façon relative par rapport à l'heure actuelle sur l'horloge de la minuterie au moment de l'appel (c'est-à-dire que new_value.it_value indique une heure relative à la valeur actuelle de l'horloge spécifiée par clockid). Un délai absolu peut être sélectionné avec le paramètre flags.
Le paramètre flags est un masque de bits qui peut avoir les valeurs suivantes :
Si le paramètre old_value n'est pas égal à NULL, la structure itimerspec vers laquelle il pointe est utilisée pour renvoyer la configuration de la minuterie au moment de l'appel ; consultez la description de timerfd_gettime() ci-dessous.
timerfd_gettime() renvoie, dans curr_value, une structure itimerspec qui contient les paramètres actuels de la minuterie auquel le descripteur de fichier fd fait référence.
Le champ it_value renvoie la durée jusqu'à la prochaine expiration. Si les deux champs de cette structure sont nuls, alors la minuterie est actuellement désactivée. Ce champ contient toujours une valeur relative, sans tenir compte d'un attribut TFD_TIMER_ABSTIME qui aurait été spécifié quand la minuterie a été configurée.
Le champ it_interval renvoie l'intervalle de la minuterie. Si les deux champs de cette structure sont nuls, alors la minuteries est configurée pour n'expirer qu'une seule fois, à l'heure spécifiée par curr_value.it_value.
Le descripteur de fichier renvoyé par timerfd_create() gère les opérations supplémentaires suivantes :
Après un fork(2), l'enfant hérite d'une copie du descripteur de fichier créé par timerfd_create(). Le descripteur de fichier se réfère au même objet minuterie sous-jacent que le descripteur de fichier correspondant dans le parent, et un read(2) de l'enfant renverra les informations sur les expirations de la minuterie.
Un descripteur de fichier créé par timerfd_create() est conservé au travers d'un execve(2), et continue à générer des expirations de minuterie si la minuterie a été armée.
S'il réussit, timerfd_create() renvoie un nouveau descripteur de fichier. En cas d'erreur, il renvoie -1 et errno est défini pour indiquer l'erreur.
En cas de réussite, timerfd_settime() et timerfd_gettime() renvoient 0. Sinon ils renvoient -1 et définissent errno pour indiquer l'erreur.
timerfd_create() peut échouer avec les erreurs suivantes :
timerfd_settime() et timerfd_gettime() peuvent échouer avec les erreurs suivantes :
timerfd_settime() peut aussi échouer avec les erreurs suivantes :
Ces appels système sont disponibles depuis Linux 2.6.25. La prise en charge de la bibliothèque est fournie depuis la glibc 2.8.
Ces appels système sont spécifiques à Linux.
En supposant le scénario suivant pour une minuterie CLOCK_REALTIME ou CLOCK_REALTIME_ALARM créée avec timerfd_create() :
Dans ce cas les événements suivants se produisent :
Actuellement, timerfd_create() prend en charge moins de types d'identifiant d'horloges que timer_create(2).
Le programme suivant crée une minuterie puis surveille sa progression. Le programme accepte jusqu'à trois paramètres en ligne de commande. Le premier paramètre spécifie le nombre de secondes pour l'expiration initiale de la minuterie. Le deuxième paramètre spécifie l'intervallse de la minuterie, en secondes. Le troisième paramètre spécifie le nombre de fois que le programme doit permettre à la minuterie d'expirer avant de quitter. Le deuxième et le troisième paramètre sont optionnels.
La session interactive suivante montre l'utilisation de ce programme :
$ a.out 3 1 100 0.000: timer started 3.000: read: 1; total=1 4.000: read: 1; total=2 ^Z # entrer Ctrl-Z pour suspendre le programme [1]+ Stopped ./timerfd3_demo 3 1 100 $ fg # Reprendre l'exécution après quelques secondes a.out 3 1 100 9.660: read: 5; total=7 10.000: read: 1; total=8 11.000: read: 1; total=9 ^C # entrer Ctrl-C pour suspendre le programme
#include <err.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <sys/timerfd.h> #include <time.h> #include <unistd.h> static void print_elapsed_time(void) { int secs, nsecs; static int first_call = 1; struct timespec curr; static struct timespec start; if (first_call) { first_call = 0; if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) err(EXIT_FAILURE, "clock_gettime"); } if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) err(EXIT_FAILURE, "clock_gettime"); secs = curr.tv_sec - start.tv_sec; nsecs = curr.tv_nsec - start.tv_nsec; if (nsecs < 0) { secs--; nsecs += 1000000000; } printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000); } int main(int argc, char *argv[]) { int fd; ssize_t s; uint64_t exp, tot_exp, max_exp; struct timespec now; struct itimerspec new_value; if (argc != 2 && argc != 4) { fprintf(stderr, "%s init-secs [interval-secs max-exp]\n", argv[0]); exit(EXIT_FAILURE); } if (clock_gettime(CLOCK_REALTIME, &now) == -1) err(EXIT_FAILURE, "clock_gettime"); /* Créer une minuterie absolue CLOCK_REALTIME avec une expiration et un intervalle initiaux comme spécifié en ligne de commande. */ new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]); new_value.it_value.tv_nsec = now.tv_nsec; if (argc == 2) { new_value.it_interval.tv_sec = 0; max_exp = 1; } else { new_value.it_interval.tv_sec = atoi(argv[2]); max_exp = atoi(argv[3]); } new_value.it_interval.tv_nsec = 0; fd = timerfd_create(CLOCK_REALTIME, 0); if (fd == -1) err(EXIT_FAILURE, "timerfd_create"); if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1) err(EXIT_FAILURE, "timerfd_settime"); print_elapsed_time(); printf("timer started\n"); for (tot_exp = 0; tot_exp < max_exp;) { s = read(fd, &exp, sizeof(uint64_t)); if (s != sizeof(uint64_t)) err(EXIT_FAILURE, "read"); tot_exp += exp; print_elapsed_time(); printf("read: %" PRIu64 "; total=%" PRIu64 "\n", exp, tot_exp); } exit(EXIT_SUCCESS); }
eventfd(2), poll(2), read(2), select(2), setitimer(2), signalfd(2), timer_create(2), timer_gettime(2), timer_settime(2), timespec(3), epoll(7), time(7)
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@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
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@lists.debian.org.
5 février 2023 | Pages du manuel de Linux 6.03 |