2013-07-06 121 views
7

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

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

并且可能下降到0.0001秒,然后打破1%的准确度。

主要问题,我有是:

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

顺便说一句,我读了睡眠甚至不长的等待时间发挥良好作用:Upper limit in Python time.sleep()? 我也看了这么短的制作时间间隔的循环来提高精确度的某处,但是当我想延迟0.01秒时,这是毫无用处的。 Karl Voigtland提到使用ctypes的nanosleep,但我觉得这是矫枉过正,那time.sleep应该做它的预期行为。

time.sleep是一个破损的python特性?或者没有人关心准确的时间测量吗?

+1

python's time.sleep()有多准确?](http://stackoverflow.com/questions/1133857/how-accurate-is-pythons-time-sleep) – g19fanatic

+0

是的,我认为这是一个OS调用,但现在我想知道为什么他们在忙碌的等待更好时使用OS调用。 – JDong

+0

一个繁忙的等待会消耗CPU时间并阻塞一个cpu。睡眠可以进行上下文切换,并且不会阻止其他执行(它会'阻止'执行)。一般来说,如果你确实需要确切的时间,那么你只能忙于等待,即使如此,你仍然仅限于操作系统对CPU的需求,这可能会背离你,无论如何... – g19fanatic

回答

4

在Windows上,OS休眠功能(Python必须使用的)只能唤醒当前定时器间隔的倍数的线程。通常这个范围在1.0毫秒和15.6毫秒之间。降低计时器的时间间隔可能是方便,因为它允许更短的睡觉,但它浪费电力,因为我在这篇文章中写道:

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/

为什么你要睡了这么短的时间段?通常最好等待发生的事情 - 等待事件 - 而不是等待这么短的时间。

+0

事实上,Python'time.sleep()'在等待期间(通过'SetConsoleCtrlHandler()'发信号通知事件)使用带有超时的'WaitForSingleObject()'调用来捕获任何Ctrl-C。) – schlenk

+0

该应用程序是一种宏;我有一套我想要非常准确地模拟的动作。我已经学会了如何在C中做到这一点,但还没有找到Python中的规范解决方案。我的问题有点无法回答,所以我现在会接受你的回答。感谢您的洞察力。 – JDong

+0

@schlenk感谢有关time.sleep()的实现的信息。有关超时何时到期的规则基本上与Sleep()相同(因为调度程序只在发生某事时或计时器中断触发时运行),所以答案仍然适用。 –

0

这是一个重复的问题,但我会尽力在这里回答它,尽我所能。

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