我使用这个来每小时产生60个事件,大多数事件发生在整分钟后的相同秒数:
import math
import time
import random
TICK = 60
TICK_TIMING = 59
TICK_MINIMUM = 30
def set_timing():
now = time.time()
elapsed = now - info['begin']
minutes = math.floor(elapsed/TICK)
tick_elapsed = now - info['completion_time']
if (info['tick']+1) > minutes:
wait = max(0,(TICK_TIMING-(time.time() % TICK)))
print ('standard wait: %.2f' % wait)
time.sleep(wait)
elif tick_elapsed < TICK_MINIMUM:
wait = TICK_MINIMUM-tick_elapsed
print ('minimum wait: %.2f' % wait)
time.sleep(wait)
else:
print ('skip set_timing(); no wait')
drift = ((time.time() - info['begin']) - info['tick']*TICK -
TICK_TIMING + info['begin']%TICK)
print ('drift: %.6f' % drift)
info['tick'] = 0
info['begin'] = time.time()
info['completion_time'] = info['begin'] - TICK
while 1:
set_timing()
print('hello world')
time.sleep(random.random()*TICK_MINIMUM)
info['tick'] += 1
info['completion_time'] = time.time()
根据实际情况,您可能会得到不同长度的 ticks:
60,60,62,58,60,60,120,30,30,60,60,60,60,60...etc.
但是在60分钟结束时,您将拥有60个刻度;其中大部分将出现在您喜欢的分钟偏移位置。
在我的系统上,我会得到小于1/20秒的典型漂移,直到需要进行校正为止。
这种方法的优点是解决了时钟漂移的问题;如果您正在执行每个tick附加一个项目的操作,并且您期望每小时附加60个项目,则未考虑漂移可能导致二次指标(如移动平均)认为数据太深入过去,从而导致错误的输出。
time.sleep(60)
也可能会比预期的早或晚返回。 - jfs