J'utilise ceci pour provoquer 60 événements par heure avec la plupart des événements se produisant au même nombre de secondes après la minute entière:
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()
Selon les conditions réelles, vous pouvez obtenir des tiques de longueur:
60,60,62,58,60,60,120,30,30,60,60,60,60,60...etc.
mais au bout de 60 minutes, vous aurez 60 ticks; et la plupart se produiront avec le décalage correct à la minute que vous préférez.
Sur mon système, j'obtiens une dérive typique de <1 / 20ème de seconde jusqu'à ce que le besoin de correction apparaisse.
L'avantage de cette méthode est la résolution de la dérive d'horloge; ce qui peut entraîner des problèmes si vous faites des choses comme ajouter un élément par tick et que vous vous attendez à 60 éléments ajoutés par heure. Le fait de ne pas tenir compte de la dérive peut amener des indications secondaires comme les moyennes mobiles à considérer les données trop profondément dans le passé, ce qui entraîne une sortie défectueuse.