11

I have to write a C program which has to sleep for milliseconds, which has to run on various platforms like Windows, Linux, Solaris, HP-UX, IBM AIX, Vxworks, and Windriver Linux

  • On Windows, the Sleep system call will work on milliseconds only.
  • On Linux, sleep will work on seconds; usleep will perform on microseconds and it's available on Solaris also.
  • In Vxworks, I hope I can implement using taskDelay and sysClkRateSet.

How can I achieve this millisecond sleep on HP-UX, IBM AIX and Wind River Linux?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
rashok
  • 12,790
  • 16
  • 88
  • 100
  • 1
    [`usleep`](http://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html) is POSIX so should be in all POSIX compliant systems (like HP/UX, AIX etc.). It's marked as obsolete though, in favor [`nanosleep`](http://pubs.opengroup.org/onlinepubs/009695399/functions/nanosleep.html) which on the other hand is marked as optional. – Some programmer dude Feb 11 '13 at 12:52
  • 1
    Note that just because you might find a way to *express* an n-millisecond delay, there's absolutely no guarantee that the host operating system will *give* you exactly what you ask for. The OS:s you list are typically not real-time, so they will very likely not guarantee things like that; when your delay ends, a more high-prio task might occupy the CPU. – unwind Feb 11 '13 at 12:57
  • Does following link answer your question? http://stackoverflow.com/questions/1157209/is-there-an-alternative-sleep-function-in-c-to-milliseconds – kunal18 Mar 28 '15 at 18:14
  • Possible duplicate of [Is there an alternative sleep function in C to milliseconds?](https://stackoverflow.com/questions/1157209/is-there-an-alternative-sleep-function-in-c-to-milliseconds) – Jonathan Leffler Jun 11 '17 at 01:06

4 Answers4

16

Propably a wrapper using platform specific #defines will do:

#if defined(WIN32)
  #include <windows.h>
#elif defined(__UNIX__)
  #include <unistd.h>
#else
#endif

...

int millisleep(unsigned ms)
{
#if defined(WIN32)
  SetLastError(0);
  Sleep(ms);
  return GetLastError() ?-1 :0;
#elif defined(LINUX)
  return usleep(1000 * ms);
#else
#error ("no milli sleep available for platform")
  return -1;
#endif
}

Update

Referring to Jonathan's comment below, please find a more modern, more portable (and as well corrected :}) version here:

#if defined(WIN32)
  #include <windows.h>
#elif defined(__unix__)
  #include <time.h>
  #include <unistd.h>
#else
#endif

...

int millisleep(unsigned ms)
{
#if defined(WIN32)

  SetLastError(0);
  Sleep(ms);
  return GetLastError() ?-1 :0;

#elif _POSIX_C_SOURCE >= 199309L

  /* prefer to use nanosleep() */

  const struct timespec ts = {
    ms / 1000, /* seconds */
    (ms % 1000) * 1000 * 1000 /* nano seconds */
  };

  return nanosleep(&ts, NULL);

#elif _BSD_SOURCE || \
  (_XOPEN_SOURCE >= 500 || \
     _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \
  !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)

  /* else fallback to obsolte usleep() */

  return usleep(1000 * ms);

#else

# error ("No millisecond sleep available for this platform!")
  return -1;

#endif
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • Under POSIX 2004, the [`usleep()`](http://pubs.opengroup.org/onlinepubs/009695399/functions/usleep.html) call was marked 'obsolescent', and it was removed from POSIX 2008. The preferred alternative is [`nanosleep()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html). The general trend in POSIX is to prefer `struct timespec`, which has nanosecond resolution, over alternatives such as `struct timeval` which has only microsecond resolution, or `usleep()` which doesn't use a structure but works with microsecond resolution too. – Jonathan Leffler Jun 11 '17 at 00:56
  • @JonathanLeffler: Thanks for notifying. Corrected. – alk Jun 11 '17 at 09:17
1

Consider select with empty FD sets and the timeout you want. From man select:

Some code calls select() with all three sets empty, nfds zero, and a non-NULL timeout as a fairly portable way to sleep with subsecond precision.

Actually it might be the best solution for any non-Windows system.

Anton Kovalenko
  • 20,999
  • 2
  • 37
  • 69
  • Thanks for your reply. currently we are using this only, in some platform `select` is not available. Like windriver linux `select` is not available. – rashok Feb 11 '13 at 12:56
  • @rashok select function exists on HP-UX and AIX. I am surprised by statement it doesn't exist on Wind River Linux. Wind River Linux is Linux, so how can it be missing the select system call? (or its newer replacements, newselect or pselect6). – Simon Kissane Feb 12 '21 at 08:40
1

I note that usleep is obsolescent but its a lot simpler than nanosleep. So I used it when I needed an enhanced sleep that would allow easy adjustment from seconds while debugging my scripts to milliseconds or zero for production.

This snooze function combines the advantages of sleep & usleep so that you can enter an int or float for your desired delay and 0.1 will sleep a 10th of a second while 3 will sleep for 3 seconds. 3.5 seconds is treated as 3 seconds.

Tested on Linux Mint 18.3 (Ubuntu 16.04.9) as C and C++ with gcc 5.4.0.

#include <unistd.h>

void snooze(double t) {(t > 1.0) ? sleep(t) : usleep(t*1000000);}

snooze(0.01);  // call function to sleep for 10ms



For completeness, this is a nanosleep version. It's potentially more accurate than the usleep version and isn't threatened by obsolescence.

#include <time.h>
#include <math.h>

void snooze(double t) {
    struct timespec req = {t, fmod(t, 1.0) * 1E9};
    nanosleep(&req, NULL);
}

// struct timespec req = {t, fmod(t, 1.0) * 1E9};
//  is equivalent to:
// struct timespec req = {0};
// req.tv_sec = t;
// req.tv_nsec = fmod(t, 1.0) * 1000000000L;

// NULL as value for *rem so no resumption after signal interrupts

snooze(1.99);  // call for delay of 1.99 seconds

As suggested by @alk, the following versions return the called sleep function's error should one occur or 0 if successful. Defining the structure rem(aining) also permits resumption after a signal interrupt.

int snooze(double t) {
    return (t > 1.0) ? sleep(t) : usleep(t*1000000);
}

int snooze(double t) {
    struct timespec req = {t, fmod(t, 1.0) * 1E9};
    struct timespec rem = {0, 0.0};
    return nanosleep(&req, &rem);
}
John 9631
  • 527
  • 5
  • 13
  • For complete completeness you might want to take care of the value returned by the functions used. – alk Apr 28 '18 at 07:35
  • Thanks for the suggestion [alk](https://stackoverflow.com/users/694576/alk). I've added options. – John 9631 Apr 28 '18 at 17:26
0

if PHP installed in windows.

this way works

php -r "usleep(200000);"

set PHP binary in global PATH.

Lo Vega
  • 121
  • 1
  • 3