【问题标题】:Time.sleep inaccurate for Python counter?Python 计数器的 Time.sleep 不准确?
【发布时间】:2015-07-16 12:11:02
【问题描述】:

我想为工作中的销售团队创建一个收入计数器,并且很想使用 Python。例如。 Joe Bloggs 将他的目标从 22.1 转移到 23.1(相差 1.0)。我希望计数器在一小时内从 22.1 均匀地滴答到 23.1。

我创建了这个脚本,它可以很好地计算一分钟(每分钟运行 2 秒);但是,当它应该运行一个小时时,它运行了 47 分钟。

问题:有人知道为什么我把它设置为一个小时后它跑得更快吗? sleep.time 不准确吗?

import time

def rev_counter(time_length):
    time_start = (time.strftime("%H:%M:%S"))

    prev_pp = 22.1
    new_pp = 23.1

    difference = new_pp - prev_pp

    iter_difference = (difference / 100000.) # Divide by 100,000 to show 10 decimal places
    time_difference = ((time_length / difference) / 100000.)     

    i = prev_pp

    while i < new_pp:
        print("%.10f" % i)
        i = i + iter_difference
        time.sleep(time_difference)

    time_end = (time.strftime("%H:%M:%S"))

    print "Time started at", time_start
    print "Time ended at", time_end

rev_counter(60) # 60 seconds. Returns 62 seconds
rev_counter(600) # 10 minutes. Returns 10 minutes, 20 secs
rev_counter(3600) # 1 hour. Returns 47 minutes

【问题讨论】:

标签: python python-2.7 time sleep


【解决方案1】:

请注意 Python 文档中time.sleep() 的引用

实际暂停时间可能少于要求的时间,因为任何 捕获的信号将在执行后终止 sleep() 信号的捕捉程序。此外,暂停时间可能会更长 比任意数量的请求,因为调度 系统中的其他活动。

作为一个建议,如果遇到这个问题,我会使用一个变量来跟踪间隔开始的时间。当 sleep 醒来时,检查是否已经过了预期的时间。如果没有,请重新启动睡眠以获取差异等。

【讨论】:

  • 谢谢。我将在其中构建时间跟踪器。
  • 我发现它花费的时间太长了。例如。 t0 = time.time(); time.sleep(1); print(time.time() - t0) 在我的机器上持续花费 8 到 11 秒。这是一个不同的问题吗?
  • 我在 Python 3.9 的文档中看到它现在说“此外,由于系统中其他活动的调度,暂停时间可能比请求的更长。”
【解决方案2】:

首先,您的循环不仅包含 sleep 语句——您在调用 time.sleep 之间所做的事情也需要时间,所以如果您重复 10 次,您将只花费 10% 的时间来做与循环进行 100 次迭代相比。

sleep.time 不准确吗?

是的。或者好吧。不错。

我来自实时信号处理背景。 PC 时钟只是有点准确,你在操作系统、标准库、脚本语言运行时间和脚本逻辑上花费的时间在硬件通知你时间已经过去的时间点和时间点之间您的软件注意到的时间很重要。

【讨论】:

  • 请注意,您的硬件也不准确(但值要低得多),准确的一点是 - 原子钟 :)
  • @reishin:这通常是用来训练我所指的时钟的:) 但即使是那些也不是很准确,因为这在物理上是不可能的(需要准确了解冲动和时间,这做不到——海森堡。”
【解决方案3】:

我刚刚注意到 time.sleep 花费的时间太长(输入值在 0.0001 到 1 秒之间的时间要长 5-30000 倍),并在寻找答案时找到了这个线程。我进行了一些测试,它一直在这样做(参见下面的代码和结果)。奇怪的是,我重新启动,然后它恢复正常,工作非常准确。当代码开始挂起时,是 time.sleep 花费了 10000 倍的时间太长了?! 所以重启是一个临时解决方案,但不确定原因是什么/永久解决方案是。

import numpy as np 
import time

def test_sleep(N,w): 
    data = []
    for i in xrange(N): 
        t0 = time.time()
        time.sleep(w)
        t1 = time.time()
        data.append(t1-t0)
    print "ave = %s, min = %s, max = %s" %(np.average(data), np.min(data), np.max(data))
    return data


data1 = test_sleep(20,.0001)
Out: ave = 2.95489487648, min = 1.11787080765, max = 3.23506307602

print data1
Out: [3.1929759979248047,
 3.121081829071045,
 3.1982388496398926,
 3.1221959590911865,
 3.098078966140747,
 3.131525993347168,
 3.12644100189209,
 3.1535091400146484,
 3.2167508602142334,
 3.1277999877929688,
 3.1103289127349854,
 3.125699996948242,
 3.1129801273345947,
 3.1223208904266357,
 3.1313750743865967,
 3.1280829906463623,
 1.117870807647705,
 1.3357980251312256,
 3.235063076019287,
 3.189779043197632]

data2 = test_sleep(20, 1)
Out: ave = 9.44276217222, min = 1.00008392334, max = 10.9998381138

print data2
Out: [10.999573945999146,
 10.999622106552124,
 3.8115758895874023,
 1.0000839233398438,
 3.3502109050750732,
 10.999613046646118,
 10.99983811378479,
 10.999617099761963,
 10.999662160873413,
 10.999619960784912,
 10.999650955200195,
 10.99962306022644,
 10.999721050262451,
 10.999620914459229,
 10.999532222747803,
 10.99965500831604,
 10.999596118927002,
 10.999563932418823,
 10.999600887298584,
 4.6992621421813965]

【讨论】:

  • 所以反复重启和重做这个实验表明 time.sleep() 在使用的​​最初几分钟后挂起。也就是说,它会准确工作几分钟,然后挂起。
猜你喜欢
  • 2018-11-03
  • 2010-11-11
  • 2017-10-02
  • 2021-04-25
  • 2013-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多