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

C 在Windows、Linux、Solaris、HP-UX、IBM AIX、Vxworks、Wind River Linux上睡眠几毫秒?,c,sleep,system-calls,milliseconds,C,Sleep,System Calls,Milliseconds,我必须编写一个睡眠时间为毫秒的C程序,它必须在各种平台上运行,如Windows、Linux、Solaris、HP-UX、IBM AIX、Vxworks和Windriver Linux 在上,睡眠系统调用将仅在毫秒内工作。 打开,睡眠将在几秒钟内起作用;usleep的运行时间为微秒,在Solaris上也可用。 在中,我希望可以使用taskDelay和sysClkRateSet实现。 如何在HP-UX、IBM AIX和Wind River Linux上实现这种毫秒睡眠?考虑使用空FD集和所需超时进行

我必须编写一个睡眠时间为毫秒的C程序,它必须在各种平台上运行,如Windows、Linux、Solaris、HP-UX、IBM AIX、Vxworks和Windriver Linux

在上,睡眠系统调用将仅在毫秒内工作。 打开,睡眠将在几秒钟内起作用;usleep的运行时间为微秒,在Solaris上也可用。 在中,我希望可以使用taskDelay和sysClkRateSet实现。 如何在HP-UX、IBM AIX和Wind River Linux上实现这种毫秒睡眠?

考虑使用空FD集和所需超时进行选择。发件人:

有些代码调用选择所有三个集合为空、nfds为零和 非空超时是一种相当可移植的亚秒睡眠方式 精确性


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

使用特定于平台的定义的包装器可能会:

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

关于,请在此处找到一个更现代、更便携和更正确的:}版本:

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

我注意到usleep已经过时,但它比nanosleep简单得多。因此,当我需要一个增强的睡眠时,我就使用了它,这样可以在调试脚本时轻松地从几秒钟调整到几毫秒或零

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

在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

POSIX是否应该在所有符合POSIX的系统(如HP/UX、AIX等)中使用。。但是,它被标记为过时,而另一方面,它被标记为可选。请注意,仅仅因为您可能找到一种表示n毫秒延迟的方法,所以绝对不能保证主机操作系统会完全满足您的要求。您列出的操作系统通常不是实时的,因此它们很可能无法保证这样的事情;当您的延迟结束时,一个更高优先级的任务可能会占用CPU。下面的链接是否回答了您的问题?谢谢你的回复,可能是重复的。目前我们仅使用此选项,在某些平台中,select不可用。Like windriver linux select不可用。@HP-UX和AIX上存在rashok select函数。我对Wind River Linux上不存在的声明感到惊讶。Wind River Linux是Linux,那么它怎么会错过select系统调用呢?或其较新的替代品,newselect或pselect6。根据POSIX 2004,该呼叫被标记为“过时”,并从POSIX 2008中删除。首选的替代方案是。POSIX的总体趋势是更喜欢具有纳秒分辨率的struct timespec,而不是只有微秒分辨率的struct timeval,或者不使用结构但也可以使用微秒分辨率的usleep。@JonathanLeffler:谢谢通知。更正。为了完整起见,您可能需要注意所用函数返回的值。谢谢您的建议。我添加了选项。
#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
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);
}