Il suffit de dormir pendant 10 secondes ou d'utiliser threading.Timer(10,foo)
entraînera une dérive de l'heure de démarrage. (Il se peut que vous ne vous en souciiez pas, ou que ce soit une source importante de problèmes, selon votre situation exacte). Il peut y avoir deux causes à cela - des inexactitudes dans le temps de réveil de votre thread ou le temps d'exécution de votre fonction.
Vous pouvez voir quelques résultats à la fin de ce post, mais d'abord un exemple de la façon de le corriger. Vous devez déterminer à quel moment votre fonction devrait être appelée et à quel moment elle a été appelée et tenir compte de la différence.
Voici une version qui dérive légèrement :
import datetime, threading
def foo():
print datetime.datetime.now()
threading.Timer(1, foo).start()
foo()
Sa sortie ressemble à ceci :
2013-08-12 13:05:36.483580
2013-08-12 13:05:37.484931
2013-08-12 13:05:38.485505
2013-08-12 13:05:39.486945
2013-08-12 13:05:40.488386
2013-08-12 13:05:41.489819
2013-08-12 13:05:42.491202
2013-08-12 13:05:43.492486
2013-08-12 13:05:44.493865
2013-08-12 13:05:45.494987
2013-08-12 13:05:46.496479
2013-08-12 13:05:47.497824
2013-08-12 13:05:48.499286
2013-08-12 13:05:49.500232
Vous pouvez voir que le nombre de sous-secondes augmente constamment et que, par conséquent, l'heure de départ "dérive".
Il s'agit d'un code qui tient compte correctement de la dérive :
import datetime, threading, time
next_call = time.time()
def foo():
global next_call
print datetime.datetime.now()
next_call = next_call+1
threading.Timer( next_call - time.time(), foo ).start()
foo()
Sa sortie ressemble à ceci :
2013-08-12 13:21:45.292565
2013-08-12 13:21:47.293000
2013-08-12 13:21:48.293939
2013-08-12 13:21:49.293327
2013-08-12 13:21:50.293883
2013-08-12 13:21:51.293070
2013-08-12 13:21:52.293393
Ici, vous pouvez voir qu'il n'y a plus d'augmentation des temps inférieurs à la seconde.
Si vos événements sont très fréquents, vous voudrez peut-être exécuter la minuterie dans un seul thread, plutôt que de démarrer un nouveau thread pour chaque événement. En tenant compte de la dérive, cela pourrait ressembler à ceci :
import datetime, threading, time
def foo():
next_call = time.time()
while True:
print datetime.datetime.now()
next_call = next_call+1;
time.sleep(next_call - time.time())
timerThread = threading.Thread(target=foo)
timerThread.start()
Cependant, votre application ne se terminera pas normalement, vous devrez tuer le fil de la minuterie. Si vous souhaitez quitter normalement votre application lorsque celle-ci est terminée, sans tuer manuellement le fil d'exécution, vous devez utiliser la commande
timerThread = threading.Thread(target=foo)
timerThread.daemon = True
timerThread.start()
0 votes
Il semble que la bibliothèque standard elle-même ne fournisse aucune fonction pour cela. Vous pouvez regarder les implémentations de boucles d'événements.
0 votes
comptage chronométré est un bon remplacement pour une boucle qui contient un appel à
time.sleep
. Elle est précise, ne dépend pas du temps d'exécution de la boucle et n'accumule pas de dérive temporelle.