Use the nanosleep Function in C

  1. Use the nanosleep Function to Suspend Program Execution With High-Resolution Timer in C
  2. Check if nanosleep Function Executed Successfully in C

This article will explain several methods of how to use the nanosleep function in C.

Use the nanosleep Function to Suspend Program Execution With High-Resolution Timer in C

nanosleep is a POSIX compliant system call for suspending the program execution for the given amount of fixed time period. Other functions also provide the facilities to do the same operation, sleep is one of them, which takes a number of seconds to suspend the calling process. sleep is said to provide the low-resolution suspension. In contrast, nanosleep allows the user to specify the sleep period with nanosecond precision.

The nanosleep function takes two addresses of type struct timespec object, both of which have two data members: tv_sec - representing the number of seconds and tv_nsec - meaning the number of nanoseconds. The first timespec structure is used to specify the time period of the suspension. Mind that, tv_nsec value must be in the range of 0 to 999999999; otherwise, the call will fail. In the following example, we execute a loop with 10 iterations and suspend the process on the 5th cycle by calling the nanosleep.

#include <stdio.h>
#include <stdlib.h>
#include <errno.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);
}

Output:

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

Check if nanosleep Function Executed Successfully in C

Even though nanosleep should suspend the process for the given period, there are events in the system that can interrupt it and force the function to return the error code and set errno to EINTR. In this case, the second timespec argument is used to store the remaining time period when the function call was interrupted by the signal. This object can subsequently call nanosleep again and hopefully finish the sleep this time. The next example demonstrates how to check for multiple error codes, print the corresponding messages, and handle code execution as needed.

#include <stdio.h>
#include <stdlib.h>
#include <errno.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);
}

Output:

Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.