11

我正在玩 python 标准库中的 time.sleep 函数,发现它不适合 sub-ms 延迟。通过测试,我发现它实际上等待 1.1-1.2 毫秒等待 1 毫秒。实施繁忙的等待使准确度在 1% 以内。我用了:

def busy_wait(dt):   
    current_time = time.time()
    while (time.time() < current_time+dt):
        pass

并且可以在 0.0001 秒内降低 1% 的准确度。

我的主要问题是:

  • 为什么睡眠功能如此不准确(可能是 C 问题)?获得具有更高时钟速度的更好的 CPU 会改变这种情况吗?
  • 为什么有人会使用睡眠?我看到的唯一优势,节能,仅限于嵌入式系统,不是吗?
  • 通过校准来补偿睡眠的不准确性是否可行?像这样:
定义睡眠(dt):
    睡眠(校准功能(dt))

顺便说一句,我读到即使等待时间长,睡眠也不能很好地发挥作用:Python time.sleep() 的上限? 我还在 SO 上的某处读到了制作更短时间间隔的循环以提高精度,但是当我想延迟 0.01 秒时这是没用的。Karl Voigtland提到使用 ctypes 的 nanosleep,但我觉得这太过分了, time.sleep 应该做它的预期行为。

time.sleep 是一个损坏的 python 功能?还是没有人足够关心准确的时间测量?

4

2 回答 2

7

在 Windows 上,操作系统睡眠功能(Python 必须使用)只能在当前计时器间隔的倍数上唤醒线程。通常,该范围在 1.0 ms 和 15.6 ms 之间。降低定时器间隔会很方便,因为它可以缩短睡眠时间,但会浪费电力,正如我在本文中所写的:

http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/

忙碌的等待可能会提供更好的准确性,但通常是一个可怕的想法,因为它会浪费更多的电力并从更值得的任务中窃取 CPU 时间:

https://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/

最后,忙等待的准确性将取决于您使用什么计时器函数来获取当前时间,并且还可能取决于计时器间隔:

https://randomascii.wordpress.com/2013/05/09/timegettime-versus-gettickcount/

为什么要睡这么短的时间?通常,最好等待某事发生——等待某个事件——而不是等待这么短的时间段。

于 2014-11-28T22:17:42.253 回答
0

这是一个重复的问题,但无论如何我都会尽我所能在这里回答它。

sleep 函数是一个操作系统调用,它与忙等待不同,它不会阻塞线程。如果你有一个多线程脚本,它不应该阻塞其他线程。睡眠功能在 Windows 中不准确,因为它不是实时操作系统(不确定这意味着什么)。如果您严格要求等待的准确性,那么忙碌的等待是您的最佳选择。否则,time.sleep()可能是首选。操作系统调用睡眠不准确的原因可能是因为它依赖于操作系统在正确的时间返回,并且依赖于操作系统调度程序的精度。

于 2014-01-30T21:59:49.620 回答