Provided by: manpages-fr-dev_4.26.0-1_all bug

NOM

       timer_create - Créer une minuterie POSIX pour un processus

BIBLIOTHÈQUE

       Bibliothèque de temps réel (librt, -lrt)

SYNOPSIS

       #include <signal.h>           /* Définition des constantes SIGEV_* */
       #include <time.h>

       int timer_create(clockid_t clockid,
                        struct sigevent *_Nullable restrict sevp,
                        timer_t *restrict timerid);

   Exigences de macros de test de fonctionnalités pour la glibc (consulter feature_test_macros(7)) :

       timer_create() :
           _POSIX_C_SOURCE >= 199309L

DESCRIPTION

       timer_create() crée une nouvelle minuterie d'intervalle par un processus. L'identifiant de cette nouvelle
       minuterie  est  renvoyé  dans  le tampon pointé par timerid, qui doit être un pointeur différent de NULL.
       L'identifiant est unique pour le processus, jusqu'à ce  que  la  minuterie  soit  détruite.  La  nouvelle
       minuterie est initialement désarmée.

       Le  paramètre  clockid indique l'horloge que la nouvelle minuterie utilise pour mesurer le temps. Il peut
       prendre une des valeurs suivantes :

       CLOCK_REALTIME
              Une horloge temps réel configurable à l'échelle du système.

       CLOCK_MONOTONIC
              Une horloge non configurable, toujours croissante qui  mesure  le  temps  depuis  un  instant  non
              spécifié dans le passé et qui ne change pas après le démarrage du système.

       CLOCK_PROCESS_CPUTIME_ID (depuis Linux 2.6.12)
              Une  horloge  qui  mesure le temps CPU (utilisateur et système) consommé par le processus appelant
              (et tous ses threads).

       CLOCK_THREAD_CPUTIME_ID (depuis Linux 2.6.12)
              Une horloge qui mesure le temps CPU (utilisateur et système) consommé par le processus appelant.

       CLOCK_BOOTTIME (depuis Linux 2.6.39)
              C'est une horloge  toujours  croissante  comme  CLOCK_MONOTONIC.  Cependant  alors  que  l'horloge
              CLOCK_MONOTONIC  ne  mesure  pas  le  temps aussi longtemps que le système est suspendu, l'horloge
              CLOCK_BOOTTIME inclut le temps pendant lequel le système est suspendu. Cela  est  utile  pour  les
              applications  qui doivent être sensibles au temps de suspension. CLOCK_REALTIME n'est pas adapté à
              ce type d'application dans  la  mesure  où  cette  horloge  est  affectée  par  des  modifications
              discontinues de l'horloge système.

       CLOCK_REALTIME_ALARM (depuis Linux 3.0)
              Cette  horloge  se  comporte  comme  CLOCK_REALTIME, mais réveillera le système s'il est suspendu.
              L'appelant doit avoir la capacité CAP_WAKE_ALARM afin de  régler  une  minuterie  utilisant  cette
              horloge.

       CLOCK_BOOTTIME_ALARM (depuis Linux 3.0)
              Cette  horloge  se  comporte  comme  CLOCK_BOOTTIME, mais réveillera le système s'il est suspendu.
              L'appelant doit avoir la capacité CAP_WAKE_ALARM afin de  régler  une  minuterie  utilisant  cette
              horloge.

       CLOCK_TAI (depuis Linux 3.10)
              Horloge dérivée d'une pendule mais qui compte les secondes intercalaires.

       Consultez clock_getres(2) pour quelques détails supplémentaires sur les horloges mentionnées.

       Comme  pour  les  valeurs  ci-dessus,  clockid  peut  être  l'identifiant  clockid renvoyé par un appel à
       clock_getcpuclockid(3) ou pthread_getcpuclockid(3).

       Le paramètre sevp pointe vers une structure sigevent qui indique comment l'appelant devrait être  notifié
       quand  la  minuterie  expire.  Pour  la définition et des détails généraux sur cette structure, consultez
       sigevent(3type).

       Le champ sevp.sigev_notify peut avoir les valeurs suivantes :

       SIGEV_NONE
              Ne pas notifier de façon asynchrone quand la minuterie expire. La progression de la minuterie peut
              être observée en utilisant timer_gettime(2).

       SIGEV_SIGNAL
              Lors de l'expiration de la minuterie, produire le signal sigev_signo pour le processus.  Consultez
              sigevent(3type)  pour  des détails généraux. Le champ si_code de la structure siginfo_t sera mis à
              SI_TIMER. À tout moment, au plus un signal est mis en attente pour le processus pour  une  horloge
              donnée ; consultez timer_getoverrun(2) pour plus de détails.

       SIGEV_THREAD
              Lors  de  l'expiration  de  la  minuterie,  appeler  sigev_notify_function  comme si elle était la
              fonction de démarrage d'un nouveau thread. Consultez sigevent(3type) pour plus de détails.

       SIGEV_THREAD_ID (spécifique à Linux)
              Comme SIGEV_SIGNAL, mais le signal est  envoyé  au  thread  dont  l'identifiant  est  fourni  dans
              sigev_notify_thread_id, qui doit être un thread du même processus que le thread appelant. Le champ
              sigev_notify_thread_id indique un identifiant de thread noyau, c'est-à-dire la valeur renvoyée par
              clone(2)  ou  gettid(2).  Ce  drapeau  n'est  destiné  à  être utilisé que par la bibliothèque des
              threads.

       Une valeur NULL pour sevp équivaut à indiquer un pointeur  vers  une  structure  sigevent  dans  laquelle
       sigev_notify  vaut  SIGEV_SIGNAL, sigev_signo vaut SIGALRM et sigev_value.sival_int vaut l'identifiant de
       l'horloge.

VALEUR RENVOYÉE

       S'il réussit, timer_create() renvoie 0 et l'identifiant de la nouvelle minuterie est placé dans *timerid.
       En cas d'erreur, il renvoie -1 et errno est défini pour indiquer l'erreur.

ERREURS

       EAGAIN Erreur temporaire lors de l'allocation de la structure de la minuterie par le noyau.

       EINVAL L'identifiant d'horloge, sigev_notify, sigev_signo ou sigev_notify_thread_id n'est pas valable.

       ENOMEM La mémoire n’a pu être allouée.

       ENOTSUP
              Le noyau ne gère pas la création d'une minuterie utilisant ce clockid.

       EPERM  clockid était CLOCK_REALTIME_ALARM ou CLOCK_BOOTTIME_ALARM, mais l'appelant n'a  pas  la  capacité
              CAP_WAKE_ALARM.

VERSIONS

   Différences entre bibliothèque C et noyau
       Une partie de l'implémentation des API de minuteries POSIX est fournie par la glibc. En particulier :

       -  L'essentiel  des  fonctionnalités  pour  SIGEV_THREAD  est implémenté dans la glibc plutôt que dans le
          noyau. (C'est forcément ainsi dans la mesure où le thread impliqué dans la gestion de la  notification
          est  un  de ceux qui doit être géré par l'implémentation des threads POSIX de la bibliothèque C.) Bien
          que  la  notification  fournie  par  le  processus  est  faite  au  moyen  d'un  thread,  en   interne
          l'implémentation de NPTL utilise une valeur sigev_notify de SIGEV_THREAD_ID en même temps qu'un signal
          en temps réel qui est réservé par l'implémentation (consultez nptl(7)).

       -  L'implémentation  du  cas  par défaut où evp est NULL est gérée dans glibc qui invoque l'appel système
          sous-jacent avec une structure sigevent remplie de façon appropriée.

       -  Les identifiants de minuteries fournis au niveau utilisateur sont maintenus par la glibc, qui fait  la
          correspondance avec les identifiants utilisés par le noyau.

STANDARDS

       POSIX.1-2008.

HISTORIQUE

       Linux 2.6. POSIX.1-2001.

       Avant Linux 2.6, la glibc fournissait une implémentation incomplète en espace utilisateur (les minuteries
       CLOCK_REALTIME  uniquement)  en  utilisant les threads POSIX, et avant la glibc 2.17, l'implémentation se
       replie sur cette technique sur les systèmes ayant un noyau antérieur à Linux 2.6.

NOTES

       Un programme peut créer plusieurs minuteries d'intervalle en utilisant timer_create().

       Les minuteries ne sont pas héritées par l'enfant d'un fork(2) et sont désarmées et  détruites  lors  d'un
       appel système execve(2).

       Le  noyau  alloue  par  avance  un  «  signal  temps  réel  en  attente » pour chaque minuterie créée par
       timer_create().  De  ce  fait,  le  nombre  de  minuteries  est  limité  par  la  limite  de   ressources
       RLIMIT_SIGPENDING (voir setrlimit(2)).

       Les  minuteries  créées par timer_create() sont communément appelées « minuteries (d'intervalle) POSIX ».
       L'API des minuteries POSIX est constituée des interfaces suivantes :

       timer_create()
              Créer une minuterie.

       timer_settime(2)
              Armer (démarrer) ou désarmer (stopper) une minuterie.

       timer_gettime(2)
              Récupérer le temps restant jusqu'à l'expiration suivante d'une minuterie, en plus de  l'intervalle
              de la minuterie.

       timer_getoverrun(2)
              Renvoyer le décompte de dépassements pour la dernière expiration de la minuterie.

       timer_delete(2)
              Désarmer et détruire une minuterie.

       Depuis  Linux  3.10,  le  fichier  /proc/pid/timers peut être utilisé pour lister les minuteries POSIX du
       processus de PID pid. Consultez proc(5) pour plus de détails.

       Depuis Linux 4.10, la prise en charge des minuteries de POSIX est une option configurable qui est activée
       par défaut. La prise en charge du noyau peut être désactivée au moyen de l'option CONFIG_POSIX_TIMERS.

EXEMPLES

       Le programme ci-dessous reçoit deux paramètres : une durée de sommeil, en seconde, et  une  fréquence  de
       minuterie  en  nanosecondes.  Le  programme  établit un gestionnaire pour le signal qu'il utilise pour la
       minuterie, puis il bloque le signal, crée et arme  une  minuterie  qui  expire  à  la  fréquence  donnée,
       s'endort  pendant  la  durée  indiquée  et  enfin débloque le signal de la minuterie. En supposant que la
       minuterie ait expiré au moins une fois pendant le sommeil du programme, le gestionnaire  de  signal  sera
       appelé  et le gestionnaire de signal affiche des informations concernant la notification de la minuterie.
       Le programme se termine après un appel au gestionnaire de signal.

       Dans l'exemple d'exécution qui suit, le  programme  s'endort  pour  une  seconde  après  avoir  créé  une
       minuterie  de  fréquence  de  100 nanosecondes. Le temps que le signal soit débloqué et fourni, il y a eu
       environ dix millions de dépassements.

           $ ./a.out 1 100
           Establishing handler for signal 34
           Blocking signal 34
           timer ID is 0x804c008
           Sleeping for 1 seconds
           Unblocking signal 34
           Caught signal 34
               sival_ptr = 0xbfb174f4;     *sival_ptr = 0x804c008
               overrun count = 10004886

   Source du programme

       #include <signal.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <time.h>
       #include <unistd.h>

       #define CLOCKID CLOCK_REALTIME
       #define SIG SIGRTMIN

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

       static void
       print_siginfo(siginfo_t *si)
       {
           int      or;
           timer_t  *tidp;

           tidp = si->si_value.sival_ptr;

           printf("    sival_ptr = %p; ", si->si_value.sival_ptr);
           printf("    *sival_ptr = %#jx\n", (uintmax_t) *tidp);

           or = timer_getoverrun(*tidp);
           if (or == -1)
               errExit("timer_getoverrun");
           else
               printf("    overrun count = %d\n", or);
       }

       static void
       handler(int sig, siginfo_t *si, void *uc)
       {
           /* Remarque : l'appel printf() à partir d'un gestionnaire de signal
              n'est pas strictement correct (et ne devrait pas être utilisé en
              production) dans la mesure où printf() n'est pas sûr dans un
              contexte de signal asynchrone ; consultez signal(7).
              Néanmoins, printf() est utilisé ici comme une manière simple de
              montrer que le gestionnaire a été appelé. */

           printf("Caught signal %d\n", sig);
           print_siginfo(si);
           signal(sig, SIG_IGN);
       }

       int
       main(int argc, char *argv[])
       {
           timer_t            timerid;
           sigset_t           mask;
           long long          freq_nanosecs;
           struct sigevent    sev;
           struct sigaction   sa;
           struct itimerspec  its;

           if (argc != 3) {
               fprintf(stderr, "Usage: %s <sleep-secs> <freq-nanosecs>\n",
                       argv[0]);
               exit(EXIT_FAILURE);
           }

           /* Établir un gestionnaire pour le signal de minuterie. */

           printf("Establishing handler for signal %d\n", SIG);
           sa.sa_flags = SA_SIGINFO;
           sa.sa_sigaction = handler;
           sigemptyset(&sa.sa_mask);
           if (sigaction(SIG, &sa, NULL) == -1)
               errExit("sigaction");

           /* Bloquer temporairement un signal de minuterie. */

           printf("Blocking signal %d\n", SIG);
           sigemptyset(&mask);
           sigaddset(&mask, SIG);
           if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
               errExit("sigprocmask");

           /* Créer la minuterie. */

           sev.sigev_notify = SIGEV_SIGNAL;
           sev.sigev_signo = SIG;
           sev.sigev_value.sival_ptr = &timerid;
           if (timer_create(CLOCKID, &sev, &timerid) == -1)
               errExit("timer_create");

           printf("timer ID is %#jx\n", (uintmax_t) timerid);

           /* Démarrer la minuterie. */

           freq_nanosecs = atoll(argv[2]);
           its.it_value.tv_sec = freq_nanosecs / 1000000000;
           its.it_value.tv_nsec = freq_nanosecs % 1000000000;
           its.it_interval.tv_sec = its.it_value.tv_sec;
           its.it_interval.tv_nsec = its.it_value.tv_nsec;

           if (timer_settime(timerid, 0, &its, NULL) == -1)
                errExit("timer_settime");

           /* Mettre en sommeil un moment : pendant ce temps,
              la minuterie peut expirer plusieurs fois */

           printf("Sleeping for %d seconds\n", atoi(argv[1]));
           sleep(atoi(argv[1]));

           /* Débloquer le signal de minuterie, de sorte que
              la notification peut être fournie */

           printf("Unblocking signal %d\n", SIG);
           if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
               errExit("sigprocmask");

           exit(EXIT_SUCCESS);
       }

VOIR AUSSI

       clock_gettime(2), setitimer(2), timer_delete(2), timer_getoverrun(2), timer_settime(2),
       timerfd_create(2), clock_getcpuclockid(3), pthread_getcpuclockid(3), pthreads(7), sigevent(3type),
       signal(7), time(7)

TRADUCTION

       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.

Pages du manuel de Linux 6.9.1                    15 juin 2024                                   timer_create(2)