Utilisez la fonction nanosleep en C

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction nanosleep pour suspendre l’exécution du programme avec une minuterie haute résolution en C
  2. Vérifiez si la fonction nanosleep a été exécutée avec succès en C
Utilisez la fonction nanosleep en C

Cet article explique plusieurs méthodes d’utilisation de la fonction nanosleep dans C.

Utilisez la fonction nanosleep pour suspendre l’exécution du programme avec une minuterie haute résolution en C

nanosleep est un appel système conforme POSIX pour suspendre l’exécution du programme pendant la durée donnée de la période de temps fixe. D’autres fonctions fournissent également les possibilités de faire la même opération, sleep est l’une d’entre elles, ce qui prend quelques secondes pour suspendre le processus d’appel. On dit que sleep fournit la suspension à basse résolution. En revanche, nanosleep permet à l’utilisateur de spécifier la période de sommeil avec une précision de l’ordre de la nanoseconde.

La fonction nanosleep prend deux adresses de type objet struct timespec, qui ont toutes deux deux membres de données: tv_sec - représentant le nombre de secondes et tv_nsec - ce qui signifie le nombre de nanosecondes. La première structure timespec est utilisée pour spécifier la durée de la suspension. Notez que la valeur de tv_nsec doit être comprise entre 0 et 999999999; sinon, l’appel échouera. Dans l’exemple suivant, nous exécutons une boucle avec 10 itérations et suspendons le processus au 5ème cycle en appelant le nanosleep.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };

int main() {
  struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};

  printf("Started loop..\n");
  for (int i = 0; i < 10; ++i) {
    printf("Iteration - %d\n", i);
    if (i == 4) {
      printf("Sleeping ....\n");
      nanosleep(&request, &remaining);
    }
  }

  exit(EXIT_SUCCESS);
}

Production:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9

Vérifiez si la fonction nanosleep a été exécutée avec succès en C

Même si nanosleep devrait suspendre le processus pendant la période donnée, il y a des événements dans le système qui peuvent l’interrompre et forcer la fonction à renvoyer le code d’erreur et à définir errno sur EINTR. Dans ce cas, le deuxième argument timespec est utilisé pour stocker la période de temps restante lorsque l’appel de fonction a été interrompu par le signal. Cet objet peut ensuite appeler à nouveau nanosleep et, espérons-le, terminer le sommeil cette fois. L’exemple suivant montre comment rechercher plusieurs codes d’erreur, imprimer les messages correspondants et gérer l’exécution du code selon les besoins.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };

int main() {
  struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};

  printf("Started loop..\n");
  for (int i = 0; i < 10; ++i) {
    printf("Iteration - %d\n", i);
    if (i == 4) {
      printf("Sleeping ....\n");

      errno = 0;
      if (nanosleep(&request, &remaining) == -1) {
        switch (errno) {
          case EINTR:
            printf("interrupted by a signal handler\n");
            exit(EXIT_FAILURE);
          case EINVAL:
            printf("tv_nsec - not in range or tv_sec is negative\n");
            exit(EXIT_FAILURE);
          default:
            perror("nanosleep");
            exit(EXIT_FAILURE);
        }
      }
    }
  }

  exit(EXIT_SUCCESS);
}

Production:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook