Verwendung der nanosleep-Funktion in C

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion nanosleep, um die Programmausführung mit einem hochauflösenden Timer in C zu unterbrechen
  2. Prüfen, ob die Funktion nanosleep in C erfolgreich ausgeführt wurde
Verwendung der nanosleep-Funktion in C

In diesem Artikel werden mehrere Methoden zur Verwendung der Funktion nanosleep in C erläutert.

Verwenden Sie die Funktion nanosleep, um die Programmausführung mit einem hochauflösenden Timer in C zu unterbrechen

nanosleep ist ein POSIX-konformer Systemaufruf, um die Programmausführung für eine bestimmte Zeitspanne zu unterbrechen. Andere Funktionen bieten ebenfalls die Möglichkeit, die gleiche Operation durchzuführen, sleep ist eine davon, die eine bestimmte Anzahl von Sekunden benötigt, um den aufrufenden Prozess zu suspendieren. Man sagt, dass sleep die niedrig aufgelöste Suspendierung bietet. Im Gegensatz dazu erlaubt nanosleep dem Benutzer, die Schlafperiode mit Nanosekunden-Präzision anzugeben.

Die Funktion nanosleep nimmt zwei Adressen vom Typ struct timespec-Objekt, die jeweils zwei Datenmitglieder haben: tv_sec - was die Anzahl der Sekunden und tv_nsec - was die Anzahl der Nanosekunden bedeutet. Die erste timespec-Struktur wird verwendet, um die Zeitspanne der Aussetzung anzugeben. Beachten Sie, dass der Wert von tv_nsec im Bereich von 0 bis 999999999 liegen muss; andernfalls wird der Aufruf fehlschlagen. Im folgenden Beispiel führen wir eine Schleife mit 10 Iterationen aus und halten den Prozess beim 5. Zyklus durch den Aufruf von nanosleep an.

#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);
}

Ausgabe:

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

Prüfen, ob die Funktion nanosleep in C erfolgreich ausgeführt wurde

Auch wenn nanosleep den Prozess für die angegebene Zeitspanne suspendieren sollte, gibt es Ereignisse im System, die ihn unterbrechen und die Funktion dazu zwingen, den Fehlercode zurückzugeben und errno auf EINTR zu setzen. In diesem Fall wird das zweite timespec-Argument verwendet, um die verbleibende Zeitspanne zu speichern, in der der Funktionsaufruf durch das Signal unterbrochen wurde. Dieses Objekt kann anschließend nanosleep erneut aufrufen und diesmal hoffentlich den Schlaf beenden. Das nächste Beispiel demonstriert, wie man auf mehrere Fehlercodes prüft, die entsprechenden Meldungen ausgibt und die Code-Ausführung nach Bedarf behandelt.

#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);
}

Ausgabe:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9
Autor: 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