通常,如果我想模拟某些作品或等待确切的时间间隔,我会使用condition_variable::wait_for
或最差thread::this_thread::sleep_for
。但condition_variable
documentation声明wait_for
或wait_until
方法可能阻止的时间超过要求的时间。
由于调度或资源争用延迟,此函数可能会阻止比
更长的 。
如何确保准确的等待间隔?
更新
我可以在没有condition_variable
的情况下联系吗?
答案 0 :(得分:7)
你不能这样做。
为了获得这样的确切保证,您需要一个实时操作系统。
C ++并不保证您使用的是实时操作系统。
因此它提供了典型的非RTOS提供的保证。
请注意,在RTOS上进行编程还有其他一些问题,远远超出了本问题的范围。
在实践中,当人们真正想要细粒度的时序控制(比如,他们正在使用每帧或每扫描线缓冲器或类似物,或音频缓冲器或其他任何东西)时,有一件事就是检查时间很短,如果是这样,旋转等待。如果时间较长,他们等待的时间少于他们想要等待的时间,然后醒来并旋转。
这也不能保证有效,但几乎适用于所有情况。
在RTOS上,平台可以提供您想要的原语。这些不在标准C ++的范围之内。没有典型的桌面操作系统是我所知道的RTOS。如果您正在为战斗机的控制硬件或类似设备编程,您可能正在使用RTOS进行编程。
我希望你不要编写战斗机控制软件并在堆栈溢出时询问这个问题。
答案 1 :(得分:0)
如果假设确实在某个确切的持续时间内进行了睡眠,然后在响应中执行了某些操作(例如获取当前时间或在屏幕上打印消息),则该操作可能会延迟一段未知的时间例如由于处理器负载。这相当于(几乎)立即发生的动作,但计时器花费的时间比预期的要长。即使在最佳情况下,计时器在您请求的时间完成,并且操作系统允许您的操作完成而不会抢占您的过程,但执行该操作需要几个时钟周期。
换句话说,在标准操作系统上,计时器在准确的时间内完成是不可能的,甚至是毫无意义的。
如何克服这个问题?一个学术上的答案是你可以使用专门的软件和硬件,比如实时操作系统,但是开发软件比定期编程要复杂得多。您可能真正想知道的是,在通常情况下,文档所指的延迟并不重要,即它通常少于1/100秒。
答案 2 :(得分:0)
使用暴力循环...例如:
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);
}
答案 3 :(得分:0)
这取决于您可以预期的准确度。一般情况下,其他人都说常规操作系统(Linux,Windows)无法保证。
<强>为什么吗
您的操作系统可能有线程概念。如果是这样,那么有一个调度程序会中断线程并将执行切换到队列中等待的其他线程。这会破坏计时器的准确性。
我该怎么办?