5 votes

Comment planifier une tâche périodique qui est immunisée contre les changements d'heure système en utilisant Python

Je suis en train d'utiliser le module sched de python pour exécuter une tâche périodiquement, et je pense avoir rencontré un bug.

J'ai constaté qu'il dépend de l'heure du système sur lequel le script python est exécuté. Par exemple, disons que je veux exécuter une tâche toutes les 5 secondes. Si j'avance l'heure du système, la tâche planifiée s'exécutera comme prévu. Cependant, si je recule l'heure du système, disons d'1 jour, alors la prochaine tâche planifiée s'exécutera dans 5 secondes + 1 jour.

Si vous exécutez le script ci-dessous et que vous changez ensuite l'heure de votre système en arrière de quelques jours, vous pourrez reproduire le problème. Le problème peut être reproduit sur Linux et Windows.

import sched
import time
import threading

period = 5
scheduler = sched.scheduler(time.time, time.sleep)

def check_scheduler():
    print time.time()
    scheduler.enter(period, 1, check_scheduler, ())

if __name__ == '__main__':
    print time.time()

    scheduler.enter(period, 1, check_scheduler, ())

    thread = threading.Thread(target=scheduler.run)
    thread.start()
    thread.join()
    exit(0)

Quelqu'un a une solution python pour contourner ce problème?

3voto

Dan Cornilescu Points 5018

From la documentation de sched:

class sched.scheduler(timefunc, delayfunc)

La classe scheduler définit une interface générique pour la planification d'événements. Il a besoin de deux fonctions pour traiter effectivement avec le "monde extérieur" - timefunc doit être appelable sans arguments et retourner un nombre (le "temps", dans n'importe quelles unités). La fonction delayfunc doit être appelable avec un argument, compatible avec la sortie de timefunc, et doit retarder ce nombre d'unités de temps. delayfunc sera également appelé avec l'argument 0 après que chaque événement soit exécuté pour permettre à d'autres threads de s'exécuter dans des applications multi-thread.

Le problème que vous avez est que votre code utilise time.time() comme timefunc, dont la valeur de retour (lorsqu'il est appelé sans arguments) est l'heure système actuelle et est donc affectée par le fait de rembobiner l'horloge système.

Pour rendre votre code immunisé contre les changements de l'heure système, vous devriez fournir un timefunc qui ne dépend pas de l'heure système, des horodatages de démarrage/actuels, etc.

Vous pouvez écrire votre propre fonction, par exemple une fonction renvoyant le nombre de secondes depuis le démarrage de votre processus, que vous devriez réellement compter dans votre code (c'est-à-dire ne le pas calculer basé sur des deltas de temps). La fonction time.clock() pourrait aider, si elle est basée sur des compteurs de temps CPU, mais je ne suis pas sûr si c'est vrai ou non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X