timerfd_create   Début   Suivant   Sommaire   Préc.page.lue   Accueil
Section: Manuel du programmeur Linux (2)
Updated: 22 février 2008
Sommaire  



NOM   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
timerfd_create, timerfd_settime, timerfd_gettime - Temporisations qui délivrent des notifications via des descripteurs de fichiers  



SYNOPSIS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
#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 *curr_value);

int timerfd_gettime(int fd, struct itimerspec *curr_value);
 



DESCRIPTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Ces appels système créent et exploitent une temporisation qui délivre des notifications d'expiration de temporisation à travers un descripteur de fichiers. Ils fournissent une alternative à l'utilisation de setitimer(2) ou timer_create(3), avec l'avantage que le descripteur de fichiers peut être surveillé par select(2), poll(2) et epoll(7).

L'utilisation de ces trois appels système est analogue à l'utilisation de timer_create(3), timer_settime(3) et timer_gettime(3). (Il n'y a pas d'analogie avec timer_gettoverrun(3), puisque cette fonctionnalité est fournie par read(2), comme décrit plus loin.)  




timerfd_create()   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
timerfd_create() crée un nouvel objet temporisation et renvoie un descripteur de fichiers qui fait référence à cette temporisation. L'argument clockid indique l'horloge qui est utilisée pour indiquer la progression de la temporisation et doit être soit CLOCK_REALTIME, soit CLOCK_MONOTONIC. CLOCK_REALTIME est une horloge configurable à l'échelle du système. CLOCK_MONOTONIC est une horloge qui n'est pas configurable et qui n'est pas affectée par des modifications discontinues de l'horloge système (par exemple, modifications manuelles du temps système). La valeur actuelle de chacune de ces horloges peut être récupérée avec clock_gettime(3).

L'argument flags est réservé pour une utilisation future. Dans Linux 2.6.25, cet argument doit être spécifié à zéro.  




timerfd_settime()   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
timerfd_settime() arme (lance) ou désarme (arrête) la temporisation référencée par le descripteur de fichiers fd.

L'argument new_value spécifie la date d'expiration initiale et l'intervalle de la temporisation. La structure itimer utilisée pour cet argument contient deux champs, chacun d'eux étant une structure de type timespec :


struct timespec {
    time_t tv_sec;                /* Seconds */
    long   tv_nsec;               /* Nanoseconds */
};

struct itimerspec {
    struct timespec it_interval;  /* Interval for periodic timer */
    struct timespec it_value;     /* Initial expiration */
};

new_value.it_value spécifie la date d'expiration initiale de la temporisation, en secondes et nanosecondes. Définir l'un des champs de new_value.it_value avec une valeur non nulle arme la temporisation. Définir les deux champs de new_value.it_value à zéro désarme la temporisation.

Définir un ou les deux champs de new_value.it_interval à une valeur non nulle spécifie la période, en secondes et nanosecondes, pour des expirations de la temporisation répétitives après la première expiration. Si les deux champs de new_value.it_interval sont nuls, la temporisation expire une seule fois, à la date spécifiée par new_value.it_value.

L'argument flags est soit 0, pour lancer une temporisation relative (new_value.it_interval spécifie un temps relatif par rapport à la valeur actuelle de l'horloge spécifiée par clockid), soit TFD_TIMER_ABSTIME, pour lancer une temporisation absolue (new_value.it_interval spécifie un temps absolu pour l'horloge spécifiée par clockid ; ainsi, la temporisation expirera lorsque la valeur de cette horloge atteindra la valeur spécifiée dans new_value.it_interval).

L'argument curr_value renvoie une structure contenant la configuration en cours de la temporisation au moment de l'appel ; voir la description de timerfd_gettime().  




timerfd_gettime()   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
timerfd_gettime() renvoie dans curr_value une structure itimerspec qui contient la configuration actuelle de la temporisation référencée par le descripteur de fichier fd.

Le champ it_value renvoie le temps restant jusqu'à la prochaine expiration de la temporisation. Si les deux champs de cette structure sont nuls, la temporisation est actuellement désarmée. Ce champ contient toujours une valeur relative, que l'attribut TFD_TIMER_ABSTIME ait été spécifié ou non lors de la configuration de la temporisation.

Le champ it_interval renvoie l'intervalle de la temporisation. Si les deux champs de cette structure sont nuls, la temporisation a été configurée pour expirer une seule fois, à la date spécifiée par curr_value.it_value.  




Opérer sur un descripteur de fichier temporisation   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Le descripteur de fichier renvoyé par timerfd_create() accepte les opérations suivantes :
read(2)
Si la temporisation a déjà expiré une ou plusieurs fois depuis que sa configuration a été modifiée avec timerfd_settime(), ou depuis le dernier appel réussi à read(2), alors le tampon fourni à read(2) renvoie un entier non signé sur 8 octets (uint64_t) contenant le nombre d'expirations qui sont survenues. (La valeur renvoyée est dans l'odre d'octet de l'hôte, c'est à dire l'ordre natif d'octet pour les entiers sur la machine hôte.)
Si aucune expiration n'est survenue au moment du read(2), l'appel soit bloquera jusqu'à la prochaine expiration de la temporisation, soit échouera avec l'erreur EAGAIN si le descripteur de fichier a été rendu non bloquant (via l'utilisation de l'opération F_SETFL de fcntl(2) pour définir l'attribut O_NONBLOCK).
Un read(2) échouera avec l'erreur EINVAL si la taille du tampon fourni est inférieure à 8 octets.
poll(2), select(2) (et semblables)
Le descripteur de fichier est accessible en lecture (l'argument readfds de select(2) ; l'atribut POLLIN de poll(2)) si une ou plusieurs expirations sont survenues.
Le descripteur de fichiers accepte également les autres API de multiplexage de descripteur de fichiers : pselect(2), ppoll(2) et epoll(7).
close(2)
Lorsque le descripteur de fichiers n'est plus nécessaire, il devrait être fermé. Lorsque tous les descripteurs de fichiers associés au même objet temporisation ont été fermés, la temporisation est désarmée et ses ressources sont libérées par le noyau.
 

Sémantique fork(2)

Après un fork(2), le fils hérite d'une copie du descripteur de fichier créé par timerfd_create(). Le descripteur de fichier fait référence au même objet temporisation sous-jacent que le descripteur de fichiers correspondant dans le parent, et les read(2) dans le fils renverront les informations relatives aux expirations de la temporisation.  

Sémantique execve(2)

Un descripteur de fichier créé avec timerfd_create() est préservé à travers un execve(2), et continue à générer des expirations de temporisation si celle-ci était armée.  



VALEUR RENVOYÉE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
S'il réussit, timerfd_create() renvoie un nouveau descripteur de fichier. S'il échoue, -1 est renvoyé et errno est définie de manière à indiquer l'erreur.

timerfd_settime() et timerfd_gettime() renvoient 0 s'ils réussissent ; s'ils échouent, ils renvoient -1 et définissent errno pour indiquer l'erreur.  




ERREURS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
timerfd_create() peut échouer avec les erreurs suivantes :
EINVAL
L'argument clockid n'est ni CLOCK_MONOTONIC, ni CLOCK_REALTIME ; ou flags n'est pas valide.
EMFILE
La limite par processus de descripteurs de fichiers ouverts a été atteinte.
ENFILE
La limite, à l'échelle du système, du nombre total de fichiers ouverts a été atteinte.
ENODEV
Impossible de monter le périphérique anonyme inode (interne).
ENOMEM
Il n'y a pas suffisamment de mémoire noyau pour créer la temporisation.

timerfd_settime() et timerfd_gettime() peuvent échouer avec les erreurs suivantes :

EBADF
fd n'est pas un descripteur de fichier valide.
EINVAL
fd n'est pas un descripteur de fichier timerfd valide. new_value n'est pas correctement initialisé (un des champs tv_nsec est hors de l'intervalle 0 à 999 999 999).
 



VERSIONS   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Ces appels systèmes sont disponibles sous Linux depuis le noyau 2.6.25. La prise en charge par la bibliothèque glibc est fournie depuis la version 2.8.  



CONFORMITÉ   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Ces appels système sont spécifiques à Linux.  



EXEMPLE   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
Le programme suivant crée une temporisation et surveille sa progression. Le programme accepte jusqu'à trois arguments sur sa ligne de commande. Le premier argument spécifie le nombre de secondes pour l'expiration initiale de la temporisation. Le second argument spécifie l'intervalle, en secondes, de la temporisation. Le troisième argument spécifie le nombre de fois que le programme autorise la temporisation à expirer avant de se terminer Les second et troisième argument de la ligne de commande sont facultatifs.

La session shell suivante montre l'utilisation du programme :


$ a.out 3 1 100
0.000: timer started
3.000: read: 1; total=1
4.000: read: 1; total=2
[type control-Z to suspend the program]
[1]+  Stopped                 ./timerfd3_demo 3 1 100
$ fg                # Resume execution after a few seconds
a.out 3 1 100
9.660: read: 5; total=7
10.000: read: 1; total=8
11.000: read: 1; total=9
[type control-C to terminate the program]

#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>        /* Definition of uint64_t */

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

static void
print_elapsed_time(void)
{
    static struct timespec start;
    struct timespec curr;
    static int first_call = 1;
    int secs, nsecs;

    if (first_call) {
        first_call = 0;
        if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
            handle_error("clock_gettime");
    }

    if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
        handle_error("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[])
{
    struct itimerspec new_value;
    int max_exp, fd;
    struct timespec now;
    uint64_t exp, tot_exp;
    ssize_t s;

    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)
        handle_error("clock_gettime");

    /* Create a CLOCK_REALTIME absolute timer with initial
       expiration and interval as specified in command line */

    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)
        handle_error("timerfd_create");

    if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
        handle_error("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))
            handle_error("read");

        tot_exp += exp;
        print_elapsed_time();
        printf("read: %llu; total=%llu\n",
                (unsigned long long) exp,
                (unsigned long long) tot_exp);
    }

    exit(EXIT_SUCCESS);
}
 



VOIR AUSSI   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil
eventfd(2), poll(2), read(2), select(2), setitimer(2), signalfd(2), timer_create(3), timer_gettime(3), timer_settime(3), epoll(7), time(7)  



TRADUCTION   Début   Précédent   Suivant   Sommaire   Préc.page.lue   Accueil

Ce document est une traduction réalisée par Alain Portal <aportal AT univ-montp2 DOT fr> le 24 avril 2008 et révisée le 6 juin 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 2 timerfd_create ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.


 



Sommaire   Début   Suivant   Sommaire   Préc.page.lue   Accueil
NOM
SYNOPSIS
DESCRIPTION
timerfd_create()
timerfd_settime()
timerfd_gettime()
Opérer sur un descripteur de fichier temporisation
Sémantique fork(2)
Sémantique execve(2)
VALEUR RENVOYÉE
ERREURS
VERSIONS
CONFORMITÉ
EXEMPLE
VOIR AUSSI
TRADUCTION

Table des mots clés   Début   Suivant   Sommaire   Préc.page.lue   Accueil
close(2)Opérer sur un descripteur de fichier temporisation
EBADFERREURS
EINVALERREURS
EMFILEERREURS
ENFILEERREURS
ENODEVERREURS
ENOMEMERREURS
poll(2), select(2) (et semblables)Opérer sur un descripteur de fichier temporisation
read(2)Opérer sur un descripteur de fichier temporisation



Ce document a été créé par man2html suivi de man2html.pl, le 17/10/2008 17:51:42, en utilisant les pages de 'man'.
 

Valid HTML 4.01 Transitional