2015-12-30 2 views
3

J'ai une exigence où je dois exécuter une tâche toutes les 5 secondes, mais seulement entre des moments précis (par exemple entre 01h30 et 02h30 demain).Comment exécuter une tâche en python à intervalles réguliers entre certains instants?

J'ai regardé le céleri, mais une tâche normale ne peut pas être exécutée de façon répétée dans le céleri et les tâches périodiques ne peuvent pas être planifiées de manière dynamique. J'ai aussi regardé APScheduler, mais cela ne supporte pas l'exécution en tant que «démon» et la planification des tâches de l'extérieur.

Une idée de ce que je pourrais utiliser pour que cela se produise? Editer: J'aurais dû le mentionner plus tôt, je dois le faire lors d'une requête web, comme une tâche en arrière-plan.

+2

Créer un travail cron? – Ashalynd

+0

Habituellement, cela est fait en utilisant l'équivalent de 'crontab' sur votre système (les fenêtres utilisées pour avoir une commande' at', ne savent pas si elle existe encore sur les versions récentes). –

Répondre

2

Si j'ai bien compris votre question, Peut-être que ça?

from time import sleep 
from datetime import datetime 


if 90 <= datetime.now().hour * 60 + datetime.now().minute <= 150: 
    # Do something 
    time.sleep(5) 

J'ai converti heure par minute pour gérer le temps plus facilement. Donc 90min est 1,30 et 150min est 2,30. (Considéré par AM)

Et le module de temps effectue cette opération à intervalles de 5 secondes.

Si vous avez également besoin de jours, vous pouvez le mettre en œuvre facilement par;

datetime.now().day 

Et vous devez mettre cela en boucle pour que la condition soit continuellement testée. La méthode de sommeil que j'ai utilisée entraînera une vérification toutes les 5 secondes.

Lorsque vous avez ajouté le code ne peut pas bloquer le processus. Une autre façon pourrait être l'utilisation de la méthode de division. Quelque chose comme;

While #condition: 
    if not datetime.now().second % 5: 
     # Process 

Mais bien sûr, je dois ajouter que c'est une mauvaise solution étant donné qu'elle fonctionne toujours. Donc, je suis sûr que l'utilisation d'une bibliothèque appropriée sera plus utile, ce qui n'est pas à ma connaissance pour le moment.

+0

'sleep' n'est pas une bonne fonction si vous avez besoin de précision. Il mettra simplement le processus dans la file d'attente verrouillée dans le planificateur, puis dans la file d'attente prête, il ne poursuivra pas le processus exactement à 5 secondes. Pour ce faire, vous devez utiliser un [signal d'horloge] (https://docs.python.org/2/library/signal.html#signal.setitimer) –

+0

Vous avez raison en effet. Je pensais juste un moyen d'éviter ce problème. :) Mais dans cet exemple, je pense que cela fonctionne comme prévu étant donné que les minutes sont divisibles par 5 – Rockybilly

+0

Merci. Mais j'ai besoin de planifier la tâche au cours d'une demande Web, il ne peut pas bloquer. Si j'exécute ce script en tant que démon et que j'ai un déclencheur une fonction à des intervalles spécifiques du code web. – Scaraffe

1

Je pense que la réponse de Rockybilly est assez proche si vous souhaitez une réponse entièrement python spécifique. Cependant, vous devrez envelopper dans un:

While True: 
#@Rockybilly's if statement 

Ceci est nécessaire afin de répéter le processus. Vous souhaitez également incorporer quelque chose comme vu ici: delay a task until certain time

Vous le feriez une fois en dehors de votre plage spécifiée (2:31 par exemple), puis dormez le script jusqu'à 1:30 le jour suivant. Cela aidera à s'assurer qu'il ne fonctionne pas constamment.

Comme les gens ont fait des commentaires, vous pouvez le faire, dans une certaine mesure, en utilisant CRON (Unix) ou le Planificateur de tâches (Windows)

-

Puisque vous avez modifié votre question, je vais ajouter une réponse à cette édition ici. S'il vous plaît voir mon commentaire ci-dessous, en réponse à @ Rockybilly, car c'est quelque chose que vous pourriez vouloir clarifier.

Vous pouvez regarder dans le threading, multiprocessing, ou les nouveaux modules asyncio si ceux-ci doivent fonctionner en parallèle.

(Impossible de lier Asyncio en raison de contraintes de répétition)

+0

Merci de m'avoir fait remarquer, j'ai ajouté qu'il y a quelques minutes :) – Rockybilly

+0

@Rockybilly Je vois ça! Génial! Je ne peux pas faire de commentaire ci-dessus (pas assez de rep), mais je pense que ce dont parle M. E dans vos commentaires, c'est que la fonction va dormir pendant 5 secondes + tout le temps nécessaire pour exécuter le script. Ainsi, si le script prend 20 secondes à s'exécuter, il en résultera des intervalles de 25 secondes. Je pense que c'est quelque chose que le PO doit clarifier. Est-ce que l'OP a besoin de résultats toutes les ~ 5 secondes? Le processus doit-il être lancé toutes les 5 secondes (sachant que les délais de résultat peuvent différer en raison de la charge)? Ou, l'exigence est juste un écart de 5 secondes entre le traitement? – disflux