【问题标题】:python periodic looping idiom?python周期性循环成语?
【发布时间】:2013-03-05 13:40:54
【问题描述】:

我有一个工作单元,我希望每 N 秒发生一次。如果我使用简单的

minute = 60
while True:
    doSomeWork()
    time.sleep(minute)

取决于doSomeWork() 需要多长时间,实际循环周期将是一分钟加上该时间。如果 doSomeWork() 所用的时间不是确定性的,那么工作的周期就更不可预测了。

我想做的是这样的

minute = 60
start = time.process_time() #? i can imagine using this, but maybe there's something better?
while True:
    doSomeWork()
    start += minute
    sleep_until(start) #? this is the function I'm in search of

(我使用的是 python 3.3)

更新:

在 Linux/OSX 上,我可以使用信号中的计时器来执行我正在寻找的操作:

import signal
import datetime

def tick(_, __):
    # doSomeWork()
    print(datetime.datetime.now())

signal.setitimer(signal.ITIMER_REAL, 60, 60)
signal.signal(signal.SIGALRM, tick)

while True:
    signal.pause()

看起来为 python3.4 开发的 tulip 东西也将使这变得容易。

【问题讨论】:

标签: python python-3.x


【解决方案1】:

sleep_until(timestamp) 基本上是time.sleep(timestamp - time.time())

您的代码实际上很好(但确保您不会通过消极时间进入睡眠仍然是一个好主意):

import time

minute = 60
next_time = time.time()
while True:
    doSomeWork()
    next_time += minute
    sleep_time = next_time - time.time()
    if sleep_time > 0:
        time.sleep(sleep_time)

 

我个人会制作一个 60 秒间隔的时间戳生成器并使用它:

import time
import itertools

minute = 60

for next_time in itertools.count(time.time() + minute, minute):
    doSomeWork()
    sleep_time = next_time - time.time()
    if sleep_time > 0:
        time.sleep(sleep_time)

【讨论】:

  • 这不会仍然引入一些偏差(尽管更少)吗?计算已经消耗的时间的表达式,加上排队剩余睡眠所需的时间,将消耗一些(小但)未计入的时间。
  • 您需要多少准确度? time.time() - start 在我的机器上需要 100 ns。你必须在一秒钟内完成 1000 万次工作才能累积。
  • 如果您一遍又一遍地这样做,您甚至可以通过使用timeit 来计算time.time 平均花费的时间。
  • @PavelAnossov 我想这是事情的原理。我已经在许多其他环境(语言/库)中使用了这种习惯用法。一旦你能做到这一点,你就不必关心这部分需要多长时间,也不必计算重要程度。
  • 如果 next_schedule 在当前时间之前,您可能想跳过sleep - 如果 doSomeWork 占用一分钟以上,就会发生这种情况。由于您使用的是itertool,因此您可以使用for 而不是whilefor next_time in scnedule: if next_time >= time.time(): sleep(next_time - time.time()) ...
猜你喜欢
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多