![](/img/trans.png)
[英]How to make a thread stop excution (eg: std::this_thread::sleep_for) for an accturate interval
[英]How to guarantee exact thread sleep interval?
通常,如果我想模拟一些工作或等待确切的时间间隔,请使用condition_variable::wait_for
或在最差的thread::this_thread::sleep_for
。 但是condition_variable
文档指出, wait_for
或wait_until
方法的阻塞时间可能比请求的时间长。
由于调度或资源争用延迟,此功能可能阻塞的时间超过timeout_duration。
如何保证准确的等待间隔?
更新
我可以在没有condition_variable
情况condition_variable
达到吗?
你不可以做这个。
为了获得这样的确切保证,您需要一个实时操作系统。
C ++不保证您使用的是实时操作系统。
因此,它提供了典型的非RTOS提供的保证。
请注意,在RTOS上进行编程还有其他复杂性,远远超出了此问题的范围。
在实践中,人们真正想要细粒度的时序控制(例如,他们与每帧或每条扫描线缓冲区之类的东西,音频缓冲区之类的东西混在一起)时,要做的一件事就是检查时间是否短,如果需要,请等待。 如果时间更长,他们等待的时间要少于他们想要等待的时间,然后醒来并旋转。
这也不能保证能正常工作,但几乎可以在所有情况下正常工作。
在RTOS上,平台可以提供所需的原语。 这些不在标准C ++的范围内。 据我所知,没有典型的台式机操作系统是RTOS。 如果您正在为战斗机的控制硬件或类似硬件进行编程,则可能是在RTOS上进行编程。
我希望您不要编写战斗机控制软件,并在堆栈溢出时询问此问题。
如果假设您确实睡了确切的一段时间,然后作为响应执行了一些操作(例如获取当前时间或将消息打印到屏幕上),则该操作可能会延迟未知的一段时间,例如由于处理器负载。 这等效于(几乎)立即发生的操作,但是计时器花费的时间比预期的要长。 即使在最佳情况下,计时器恰好在您请求的时间完成,并且操作系统允许您在不抢占进程的情况下完成操作,但仍需要几个时钟周期来执行该操作。
因此,换句话说,在标准操作系统上,计时器无法准确地在请求的时间完成,甚至是没有意义的。
如何克服? 一个学术上的答案是,您可以使用专用软件和硬件(例如实时操作系统),但是要开发用于常规编程的软件要复杂得多。 您可能真正想知道的是,在通常情况下,文档所指的延迟并不大,即通常小于1/100秒。
使用蛮力循环...例如:
chrono::microseconds sleep_duration{1000};
auto now = chrono::high_resolution_clock::now()
while(true)
{
auto elapsed = chrono::duration_cast<hrono::microseconds>(chrono::high_resolution_clock::now() - now);
if (elapsed > sleep_duration)
break;
}
这有点丑陋,但桌面操作系统不是实时的,因此您无法拥有如此的精度。
为了放松CPU,您可以查看以下代码段:
void little_sleep(std::chrono::microseconds us)
{
auto start = std::chrono::high_resolution_clock::now();
auto end = start + us;
do {
std::this_thread::yield();
} while (std::chrono::high_resolution_clock::now() < end);
}
这取决于您可以期望的精度。 通常,正如其他人所说,常规操作系统(Linux,Windows)不能保证这一点。
为什么?
您的操作系统可能具有线程的概念。 如果是这样,那么有一个调度程序可以中断线程并将执行切换到队列中等待的其他线程。 这会破坏计时器的准确性。
我该怎么办?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.