Sleeping for milliseconds on Windows, Linux, Solaris, HP-UX, IBM AIX, Vxworks, Wind River Linux?

后端 未结 3 987
深忆病人
深忆病人 2020-12-10 13:02

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 L

相关标签:
3条回答
  • 2020-12-10 13:40

    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
    }
    
    0 讨论(0)
  • 2020-12-10 13:43

    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);
    }
    
    0 讨论(0)
  • 2020-12-10 13:52

    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.

    0 讨论(0)
提交回复
热议问题