繁体   English   中英

对于`std :: this_thread :: sleep_for()`有任何特定于平台的限制吗?

[英]Are there any platform-specific limitations to `std::this_thread::sleep_for()`?

在使用std::this_thread::sleep_for()毫秒和向上时,是否有任何已知的可移植性问题需要考虑?

在我正在开发的一个项目中,我希望能够替换一系列特定于平台的实现,这些实现都是为了产生指定的毫秒数而提供或者使用,使用从Microsoft的Sleep()naonsleep()usleep任何东西,具体取决于在特定平台上可用的内容。 其中一些具有明显的局限性,例如在某些平台上不支持1000毫秒或更长的延迟。

std::this_thread::sleep_for()遭受这样的怪癖吗?

最大睡眠持续时间: std::this_thread::sleep_for()在这里没有任何问题。 只要你愿意,你就可以睡觉。

精度: std::this_thread::sleep_for()有同样的问题,你提到的所有其他睡眠功能也有: 可能不是! 见下面的更新!

当您的任务实际恢复时,任何睡眠功能都会受到这样的quirk ,即它完全取决于操作系统中的调度程序。 您的睡眠时间通常会在抢占式多任务调度程序的最小时间片周围有所不同。

更糟糕的是,这个时间片在所有操作系统上并不总是不变的。

在Linux上,您通常有10毫秒的时间片,睡眠时间小于10毫秒可能导致睡眠时间为0毫秒。 睡眠10毫秒可能导致睡眠 10毫秒或更长时间,可能但不一定与时间片大小对齐。

简而言之:您根本无法依赖任何睡眠函数,包括std::this_thread::sleep_for()

还有另一类睡眠功能,可以忙着等待。 这通常在等待明显短于调度时间片(例如2 us)的时间时使用。 但是,当然即使这可能是非常不准确的,因为即使在几乎空闲的系统上你的任务也可能被抢占,然后你可以为你的2 us睡眠时间增加10 ms。

在多任务操作系统上,您没有机会:您无法准确入睡。 睡眠功能有错误,甚至有系统错误,因此睡眠100次10毫秒可能会在0到2秒之间睡眠。

如果您有长期时间要求,您唯一的机会就是不断查询挂钟时间。

更新:Linux和macOS的基准测试:

至少在Linux和macOS上, std::this_thread::sleep_for()对于毫秒分辨率非常精确,因此不会受到我上面描述的所有工件的影响:

Linux基准测试:每次睡眠被重复调用,持续时间为一秒,并给出实际平均睡眠时间(例如,平均超过200次睡眠呼叫(5毫秒)):

std::this_thread::sleep( 1 ms) slept really 1.13915 ms
std::this_thread::sleep( 2 ms) slept really 2.15215 ms
std::this_thread::sleep( 3 ms) slept really 3.14976 ms
std::this_thread::sleep( 4 ms) slept really 4.15059 ms
std::this_thread::sleep( 5 ms) slept really 5.15062 ms
std::this_thread::sleep( 6 ms) slept really 6.15008 ms
std::this_thread::sleep( 7 ms) slept really 7.14988 ms
std::this_thread::sleep( 8 ms) slept really 8.14979 ms
std::this_thread::sleep( 9 ms) slept really 9.15044 ms
std::this_thread::sleep(10 ms) slept really 10.1504 ms
std::this_thread::sleep(11 ms) slept really 11.1511 ms
std::this_thread::sleep(12 ms) slept really 12.1505 ms
std::this_thread::sleep(13 ms) slept really 13.1504 ms
std::this_thread::sleep(14 ms) slept really 14.1501 ms
std::this_thread::sleep(15 ms) slept really 15.1503 ms
std::this_thread::sleep(16 ms) slept really 16.1499 ms
std::this_thread::sleep(17 ms) slept really 17.1505 ms
std::this_thread::sleep(18 ms) slept really 18.1505 ms
std::this_thread::sleep(19 ms) slept really 19.1504 ms
std::this_thread::sleep(20 ms) slept really 20.1505 ms

对于macOS也是如此:

std::this_thread::sleep( 1 ms) slept really 1.27451 ms
std::this_thread::sleep( 2 ms) slept really 2.45646 ms
std::this_thread::sleep( 3 ms) slept really 3.61991 ms
std::this_thread::sleep( 4 ms) slept really 4.77443 ms
std::this_thread::sleep( 5 ms) slept really 5.7994 ms
std::this_thread::sleep( 6 ms) slept really 7.03769 ms
std::this_thread::sleep( 7 ms) slept really 8.13089 ms
std::this_thread::sleep( 8 ms) slept really 9.13276 ms
std::this_thread::sleep( 9 ms) slept really 10.441 ms
std::this_thread::sleep(10 ms) slept really 11.5895 ms
std::this_thread::sleep(11 ms) slept really 12.77 ms
std::this_thread::sleep(12 ms) slept really 13.8207 ms
std::this_thread::sleep(13 ms) slept really 14.9366 ms
std::this_thread::sleep(14 ms) slept really 16.4569 ms
std::this_thread::sleep(15 ms) slept really 17.27 ms
std::this_thread::sleep(16 ms) slept really 18.2013 ms
std::this_thread::sleep(17 ms) slept really 19.6347 ms
std::this_thread::sleep(18 ms) slept really 20.7785 ms
std::this_thread::sleep(19 ms) slept really 22.9571 ms
std::this_thread::sleep(20 ms) slept really 23.2532 ms

两次运行都在空闲系统上。 有趣的是:在Linux上,数字在加载的系统上变得更加精确(在屏幕会话中是的)。 调度器工件! 但小的! :-)

这适用于Linux上的usleep() :也非常精确。 我不再相信我上面写的内容:

usleep( 1 ms) slept really  1.148 ms
usleep( 2 ms) slept really  2.152 ms
usleep( 3 ms) slept really  3.151 ms
usleep( 4 ms) slept really  4.151 ms
usleep( 5 ms) slept really  5.149 ms
usleep( 6 ms) slept really  6.149 ms
usleep( 7 ms) slept really  7.149 ms
usleep( 8 ms) slept really  8.150 ms
usleep( 9 ms) slept really  9.150 ms
usleep(10 ms) slept really 10.150 ms
usleep(11 ms) slept really 11.149 ms
usleep(12 ms) slept really 12.149 ms
usleep(13 ms) slept really 13.150 ms
usleep(14 ms) slept really 14.150 ms
usleep(15 ms) slept really 15.149 ms
usleep(16 ms) slept really 16.149 ms
usleep(17 ms) slept really 17.150 ms
usleep(18 ms) slept really 18.150 ms
usleep(19 ms) slept really 19.149 ms
usleep(20 ms) slept really 20.149 ms

sleep_for支持更长的延迟,因为它接受任何有效的持续时间值。 但是,它确实有局限性:

sleep_for通常使用std::chrono::steady_clock ,因此受到该时钟的限制。 该标准要求时钟单调前进。 但决议可能因实施而异。

也,

由于调度或资源争用延迟,此功能可能会阻塞比sleep_duration更长的时间。 sleep_for(cpp参考)

所以sleep_for可能会睡眠时间超过指定时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM