C语言 在 Windows、Linux、Solaris、HP-UX、IBM AIX、Vxworks、Wind River Linux 上休眠几毫秒?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14812233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:19:35  来源:igfitidea点击:

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

csleepsystem-callsmilliseconds

提问by rashok

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

我必须编写一个 C 程序,它必须休眠几毫秒,它必须在 Windows、Linux、Solaris、HP-UX、IBM AIX、Vxworks 和 Windriver Linux 等各种平台上运行

  • On Windows, the Sleepsystem call will work on milliseconds only.
  • On Linux, sleepwill work on seconds; usleepwill perform on microseconds and it's available on Solaris also.
  • In Vxworks, I hope I can implement using taskDelayand sysClkRateSet.
  • Windows 上Sleep系统调用只会在毫秒内工作。
  • Linux 上sleep将在几秒钟内工作;usleep将在微秒内执行,它也可以在 Solaris 上使用。
  • Vxworks 中,我希望我可以使用taskDelayand来实现sysClkRateSet

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

如何在 HP-UX、IBM AIX 和 Wind River Linux 上实现这种毫秒级睡眠?

回答by alk

Propably a wrapper using platform specific #defines will do:

使用特定于平台的包装器#define可能会这样做:

#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
}

回答by Anton Kovalenko

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

考虑select空 FD 集和您想要的超时。来自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.

一些代码调用 select() ,所有三个集合都为空,nfds 为零,以及非 NULL 超时,作为一种相当便携的睡眠方式,以亚秒级精度。

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

实际上,它可能是任何非 Windows 系统的最佳解决方案。

回答by John 9631

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.

我注意到 usleep 已经过时了,但它比 nanosleep 简单得多。因此,我在需要增强睡眠时使用它,以便在调试脚本时从几秒钟轻松调整到毫秒或零以进行生产。

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.

此贪睡功能结合了 sleep 和 usleep 的优点,因此您可以输入 int 或 float 以获得所需的延迟,0.1 将休眠 10 秒,而 3 将休眠 3 秒。3.5 秒被视为 3 秒。

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

在 Linux Mint 18.3 (Ubuntu 16.04.9) 上测试为 C 和 C++,使用 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.

为了完整起见,这是一个 nanosleep 版本。它可能比 usleep 版本更准确,并且不会受到过时的威胁。

#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.

正如@alk所建议的那样,以下版本将返回被调用的睡眠函数的错误,如果发生或成功则返回 0。定义结构 rem(aining) 还允许在信号中断后恢复。

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);
}