Я використовую це, щоб викликати 60 подій на годину, при цьому більшість подій відбувалися за ту ж кількість секунд після всієї хвилини:
import math
import time
import random
TICK = 60 # one minute tick size
TICK_TIMING = 59 # execute on 59th second of the tick
TICK_MINIMUM = 30 # minimum catch up tick size when lagging
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')
#random real world event
time.sleep(random.random()*TICK_MINIMUM)
info['tick'] += 1
info['completion_time'] = time.time()
Залежно від реальних умов у вас можуть з’явитися кліщі довжини:
60,60,62,58,60,60,120,30,30,60,60,60,60,60...etc.
але наприкінці 60 хвилин у вас буде 60 кліщів; і більшість з них відбуватиметься при правильному зміщенні до тієї хвилини, яку ви віддаєте перевагу.
У моїй системі я отримую типовий дрейф <1/20 секунди, поки не з’явиться потреба в корекції.
Перевагою цього способу є дозвіл дрейфу годинника; що може спричинити проблеми, якщо ви робите такі речі, як додавання одного елемента за галочку, і ви очікуєте 60 доданих елементів на годину. Незрахунок дрейфу може спричинити, що вторинні ознаки, такі як ковзаючі середні, вважають дані занадто глибокими в минуле, що призводить до несправного виведення.