NANOSLEEP(2)

NOM
nanosleep - Sommeil en haute résolution

SYNOPSIS
#include <time.h>

int nanosleep(const struct timespec *req, struct timespec *rem);

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

nanosleep():
    _POSIX_C_SOURCE >= 199309L

DESCRIPTION
nanosleep() suspend l'exécution du thread appelant jusqu'à ce que le temps indiqué dans *req ait expiré, ou que la réception d'un signal ait déclenché l'invocation d'un gestionnaire dans le thread appelant ou ait terminé le processus.

Si l'appel est interrompu par un gestionnaire de signal nanosleep() renvoie -1, renseigne errno avec la valeur EINTR, et inscrit le temps restant dans la structure pointée par rem à moins que rem soit NULL. La valeur de *rem peut être utilisée pour rappeler à nouveau nanosleep() afin de terminer la pause (mais voir la section NOTES plus loin).

La structure timespec est utilisée pour indiquer l'intervalle de temps en nanosecondes. Elle est définie comme ceci :

    struct timespec {
        time_t tv_sec;        /* secondes     */
        long   tv_nsec;       /* nanosecondes */
    };

La valeur du champ nanosecondes doit être dans l'intervalle 0 à 999 999 999.

Par rapport à sleep(3) et usleep(3), nanosleep() a les avantages suivants : il fournit une meilleure résolution pour indiquer la durée du sommeil ; POSIX.1 indique explicitement qu'il n'interagit avec aucun signal ; il permet enfin de continuer facilement un sommeil interrompu par un signal.

VALEUR RENVOYÉE
L'appel nanosleep() renvoie 0 s'il réussit à suspendre l'exécution pour la durée demandée. Si l'appel est interrompu par un gestionnaire de signal ou rencontre une erreur, il renvoie -1 et errno contient le code d'erreur.

ERREURS

EFAULT
    Problème lors de la copie d'information à partir de l'espace utilisateur.

EINTR
    La pause a été interrompue par un signal délivré au thread (voir signal(7)). Le temps restant de sommeil a été inscrit dans *rem pour que le thread puisse terminer facilement son sommeil en rappelant nanosleep().

EINVAL
    La valeur du champ tv_nsec n'est pas dans l'intervalle 0 à 999 999 999 ou tv_sec est négatif.

CONFORMITÉ
POSIX.1-2001, POSIX.1-2008.

NOTES
Si l'intervalle indiqué dans req n'est pas un multiple exact de la granularité de l'horloge sous-jacente (consultez time(7)), l'intervalle est arrondi au multiple supérieur. De plus, après que le sommeil est achevé, il y a toujours un délai avant que le processeur ne redevienne complètement disponible pour le thread appelant.

Le fait que nanosleep() endorme pour une durée relative peut être problématique si l'appel est relancé de manière répétée après avoir été interrompu par des signaux, puisque le temps entre les interruptions et les redémarrages de l'appel connaîtra une dérive lorsque le sommeil sera finalement achevé. Ce problème peut être évité en utilisant clock_nanosleep(2) avec une valeur de temps absolu.

POSIX.1 indique que nanosleep() doit mesurer le temps avec l'horloge CLOCK_REALTIME. Pourtant, Linux mesure le temps avec l'horloge CLOCK_MONOTONIC. Cela n'a probablement pas d'importance car la spécification POSIX.1 de clock_settime(2) indique que les modifications discontinues dans CLOCK_REALTIME n'affectent pas nanosleep() :

    Configurer la valeur de l'horloge CLOCK_REALTIME avec clock_settime(2) ne doit pas avoir d'effet sur les threads bloqués attendant un service de temps relatif basé sur cette horloge. Cela inclut la fonction nanosleep() ; ... En conséquence, ces services de temps doivent expirer lorsque la durée relative demandée est atteinte, indépendamment de l'ancienne ou la nouvelle valeur de l'horloge.

  Ancien comportement
Pour gérer des applications nécessitant des pauses plus précises (par exemple pour le contrôle de périphériques matériels avec un délai critique), nanosleep() prend en charge des pauses jusqu'à 2 millisecondes, en étant occupé avec une précision d’une microseconde lorsqu'il est appelé à partir d'un thread ordonnancé par une politique en temps réel comme SCHED_FIFO ou SCHED_RR. Cette extension spéciale a été supprimée dans le noyau 2.5.39, et n'est donc plus disponible dans les noyaux 2.6.0 et supérieur.

BOGUES
Si un programme captant les signaux et utilisant nanosleep() reçoit des signaux à très haute vitesse, les délais d'ordonnancement et les erreurs d'arrondi de calcul par le noyau de l'intervalle de sommeil et de la valeur de retour remain signifient que la valeur de remain peut augmenter régulièrement au cours des redémarrages successifs de l'appel nanosleep(). Pour éviter de tels problèmes, utilisez clock_nanosleep(2) avec l'attribut TIMER_ABSTIME pour un sommeil d'une durée absolue.

Dans Linux 2.4, si nanosleep() est arrêté par un signal (par exemple, SIGTSTP), l'appel échoue avec l'erreur EINTR après que le thread a repris avec un signal SIGCONT. Si l'appel système est, par la suite, relancé, le temps passé par le thread dans l'état arrêté n'est pas comptabilisé dans l'intervalle de sommeil. Ce problème est corrigé dans les noyaux Linux 2.6.0 et supérieurs.

VOIR AUSSI
clock_nanosleep(2), restart_syscall(2), sched_setscheduler(2), timer_create(2), sleep(3), usleep(3), time(7)

COLOPHON
Cette page fait partie de la publication 5.13 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/.

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> et Jean-Philippe MENGUAL <jpmengual@debian.org> Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) 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.