对于`std :: this_thread :: sleep_for()`有任何特定于平台的限制吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对于`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 reference)
因此,sleep_for
可能会睡眠时间超过指定时间。
以上是关于对于`std :: this_thread :: sleep_for()`有任何特定于平台的限制吗?的主要内容,如果未能解决你的问题,请参考以下文章
std::this_thread::sleep_for - 上下文切换到这个线程吗?
C++ std::this_thread::yield()函数(线程抑制线程让步让出时间片)volatile
std::this_thread::sleep_until 时间完全偏离了大约 2 倍,莫名其妙
是否为 C++11 中的信号中断(或信号处理程序)定义了 std::this_thread::sleep_for 行为?