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

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

  • 在Windows上 , Sleep系统调用仅在毫秒内有效。
  • 在Linux上 , sleep将在几秒钟内完成; usleep将在微秒上执行,它也可以在Solaris上使用。
  • 在Vxworks中 ,我希望我可以使用taskDelaysysClkRateSet来实现。

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

可以使用特定于平台的#define s的包装器可以:

 #if defined(WIN32) #include  #elif defined(__UNIX__) #include  #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 } 

更新

请参阅下面的Jonathan的评论 ,请在这里找到更现代,更便携(以及更正:})的版本:

 #if defined(WIN32) #include  #elif defined(__unix__) #include  #include  #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 } 

考虑select空FD集和所需的超时。 从man select

有些代码调用select(),其中所有三个组都为空,nfds为零,非NULL超时作为一种相当便携的方式以亚秒级精度进行hibernate。

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

我注意到usleep已经过时,但它比nanosleep简单得多。 因此,当我需要增强的睡眠时,我会使用它,这样可以在几秒钟内轻松调整,同时将脚本调试为毫秒或零以进行生产。

这个贪睡function结合了睡眠和睡眠的优点,这样你就可以输入一个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  void snooze(double t) {(t > 1.0) ? sleep(t) : usleep(t*1000000);} snooze(0.01); // call function to sleep for 10ms 


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

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

正如@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); }