200

I have some source code that was compiled on Windows. I am converting it to run on Red Hat Linux.

The source code has included the <windows.h> header file and the programmer has used the Sleep() function to wait for a period of milliseconds. This won't work on the Linux.

However, I can use the sleep(seconds) function, but that uses integer in seconds. I don't want to convert milliseconds to seconds. Is there a alternative sleep function that I can use with gcc compiling on Linux?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ant2009
  • 27,094
  • 154
  • 411
  • 609
  • `sleep(/*seconds*/)` in `` works, but if i use with `printf("some things")` without `\n`, its not works. – EsmaeelE Nov 26 '17 at 13:33
  • 1
    For use in this case, we must flushing the output with `fflush(stdout);` after each `printf()` – EsmaeelE Nov 26 '17 at 13:47

5 Answers5

273

Yes - older POSIX standards defined usleep(), so this is available on Linux:

int usleep(useconds_t usec);

DESCRIPTION

The usleep() function suspends execution of the calling thread for (at least) usec microseconds. The sleep may be lengthened slightly by any system activity or by the time spent processing the call or by the granularity of system timers.

usleep() takes microseconds, so you will have to multiply the input by 1000 in order to sleep in milliseconds.


usleep() has since been deprecated and subsequently removed from POSIX; for new code, nanosleep() is preferred:

#include <time.h>

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

DESCRIPTION

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.

The structure timespec is used to specify intervals of time with nanosecond precision. It is defined as follows:

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

An example msleep() function implemented using nanosleep(), continuing the sleep if it is interrupted by a signal:

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

/* msleep(): Sleep for the requested number of milliseconds. */
int msleep(long msec)
{
    struct timespec ts;
    int res;

    if (msec < 0)
    {
        errno = EINVAL;
        return -1;
    }

    ts.tv_sec = msec / 1000;
    ts.tv_nsec = (msec % 1000) * 1000000;

    do {
        res = nanosleep(&ts, &ts);
    } while (res && errno == EINTR);

    return res;
}
Neuron
  • 5,141
  • 5
  • 38
  • 59
caf
  • 233,326
  • 40
  • 323
  • 462
  • 73
    Why do they keep deprecating simple functions for complicated functions. Instead of busting your brains on nanosecond() might as well use usleep for the time being. –  Jun 06 '19 at 09:02
  • 1
    usleep can't do nano seconds while nanosleep should – Anton Krug Aug 26 '20 at 17:48
  • 5
    @AntonKrug In many environments, even microsecond precision is not realistically achievable. – Erich Kitzmueller Dec 28 '20 at 13:17
  • 2
    @ErichKitzmueller embedded and bare-metal environments can achieve ~50ns. And it depends how the HAL and the libraries were implemented. For example you can invoke fopen on targets that do not even have filesystem (to output characters to UARTs). And call printf on devices which do not have screens. And yet often the code is fully portable between x86 hosts and embedded targets. – Anton Krug Dec 29 '20 at 01:46
73

You can use this cross-platform function:

#ifdef WIN32
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
#include <time.h>   // for nanosleep
#else
#include <unistd.h> // for usleep
#endif

void sleep_ms(int milliseconds){ // cross-platform sleep function
#ifdef WIN32
    Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
    struct timespec ts;
    ts.tv_sec = milliseconds / 1000;
    ts.tv_nsec = (milliseconds % 1000) * 1000000;
    nanosleep(&ts, NULL);
#else
    if (milliseconds >= 1000)
      sleep(milliseconds / 1000);
    usleep((milliseconds % 1000) * 1000);
#endif
}
Bernardo Ramos
  • 4,048
  • 30
  • 28
  • 3
    When we don't have `_POSIX_C_SOURCE >= 199309L`, as in the case of `-ansi` or `-std=c89`, I would recommend using `struct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = milliseconds % 1000 * 1000; select(0, NULL, NULL, NULL, &tv);` instead of `usleep(milliseconds * 1000);`. Credit goes [here](http://stackoverflow.com/a/264378/5472899). – Josh Sanford Sep 29 '16 at 18:18
  • 1
    Great answer! Note, here's the `nanosleep()` documentation: http://man7.org/linux/man-pages/man2/nanosleep.2.html. Posting the documentation links for each platform-specific function used here would be useful. – Gabriel Staples Apr 26 '19 at 02:23
  • Also note that when compiling with `gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test` on Linux Ubuntu, with gcc version 4.8.4, I get the following warning: `warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]`. The solution is to **add the following 2 defines to the very top of your code:** 1) `#define __USE_POSIX199309` and 2) `#define _POSIX_C_SOURCE 199309L`. **Both** are required to get the code to compile without any warnings (and to also use the `nanoseconds()` function, which it has available). – Gabriel Staples Apr 26 '19 at 02:44
  • Related answer I just made: https://stackoverflow.com/a/55860234/4561887 – Gabriel Staples Apr 26 '19 at 03:02
  • In my case on Linux, `_POSIX_C_SOURCE` starts out undefined so `unistd.h` gets included. The include of `unistd.h` causes `_POSIX_C_SOURCE` to get defined to something above `199309L`. Therefore inside `void sleep_ms()` the `nanosleep` version gets chosen by the preprocessor which leads to a compilation error from `time.h` not being included. If I add `#include ` at the top that causes it to be defined for the first block. `stdlib.h` is a random choice that was likely to define `_POSIX_C_SOURCE`. – Philippe Carphin Jul 18 '23 at 18:59
33

Alternatively to usleep(), which is not defined in POSIX 2008 (though it was defined up to POSIX 2004, and it is evidently available on Linux and other platforms with a history of POSIX compliance), the POSIX 2008 standard defines nanosleep():

nanosleep - high resolution sleep

#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

The nanosleep() function shall cause the current thread to be suspended from execution until either the time interval specified by the rqtp argument has elapsed or a signal is delivered to the calling thread, and its action is to invoke a signal-catching function or to terminate the process. The suspension time may be longer than requested because the argument value is rounded up to an integer multiple of the sleep resolution or because of the scheduling of other activity by the system. But, except for the case of being interrupted by a signal, the suspension time shall not be less than the time specified by rqtp, as measured by the system clock CLOCK_REALTIME.

The use of the nanosleep() function has no effect on the action or blockage of any signal.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
28

Beyond usleep, the humble select with NULL file descriptor sets will let you pause with microsecond precision, and without the risk of SIGALRM complications.

sigtimedwait and sigwaitinfo offer similar behavior.

pilcrow
  • 56,591
  • 13
  • 94
  • 135
  • 1
    'without the risk of sigalarm' : which risk and which case ? calling sleep and usleep ? – Massimo Mar 21 '18 at 20:19
  • 3
    @Massimo, the linked spec for _usleep_ has several sentences on unspecified SIGALARM behavior. (Basically, _usleep_ and _sleep_ are allowed to be implemented via the old _alarm_ mechanism, which you can imagine would complicate safe usage of _usleep_ and SIGALARM. I don't know of any modern system that does it this way, but it's still in the spec.) – pilcrow Nov 14 '18 at 14:08
16
#include <unistd.h>

int usleep(useconds_t useconds); //pass in microseconds
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278