We don’t have millisecond level control in the sleep() function. But in Linux we can implement our own function that will take duration in milliseconds as input and sleep for that duration.
Using usleep()
The usleep() function takes input as micro seconds. We can write our own function that’ll take input as millisecond. We can simply pass that value multiplying by 1000 to usleep() function.
#include <unistd.h> int msleep(unsigned int tms) { return usleep(tms * 1000); }
This implementation is good enough but only thing is that the usleep() function is now deprecated. We have few other options also.
Using nanosleep()
We can implement our msleep() function using nanosleep() which takes timespec structure as input. It has nano second level control. We can convert the input milliseconds into second and nanoseconds before calling the nanosleep() function.
#include <errno.h> #include <time.h> int msleep(long tms) { struct timespec ts; int ret; if (tms < 0) { errno = EINVAL; return -1; } ts.tv_sec = tms / 1000; ts.tv_nsec = (tms % 1000) * 1000000; do { ret = nanosleep(&ts, &ts); } while (ret && errno == EINTR); return ret; }
You might notice that there is a loop around nanosleep() function. To understand this we need to understand the behavior of nanosleep() function.
From the man page of nanospleep.
nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed, or the delivery of a signal that triggers the invocation of a handler in the calling thread or that terminates the process.
If the call is interrupted by a signal handler, nanosleep() returns -1, sets errno to EINTR, and writes the remaining time into the structure pointed to by rem unless rem is NULL. The value of *rem can then be used to call nanosleep() again and complete the specified pause.
If the function gets interrupted before elapsing the specified time, return value (ret) would be -1 and errno would be EINTR. As we passed ts as both parameters, remaining time will be set to the ts itself. We are calling the function with remaining time (modified ts). This process will continue until the total specified time is elapsed.
Using select()
We use select() function to detect whether any file descriptor is set. If we don’t pass any file descriptor, then it will time out after the specified time is elapsed. Here also we’ll have millisecond level control.
#include <sys/time.h> void msleep(int tms) { struct timeval tv; tv.tv_sec = tms / 1000; tv.tv_usec = (tms % 1000) * 1000; select (0, NULL, NULL, NULL, &tv); }
The post C Program to Sleep in Milliseconds appeared first on QnA Plus.