Le module sched implémente une horloge, un programmateur permettant de lancer des tâches à des moments bien précis. Dans ce qui suit, "programme" est à prendre dans le sens : ce qui a été programmé dans le programmateur.
lien : pymotw
Le constructeur de la classe sched reçoit deux arguments : l'heure actuelle, et une fonction d'attente, fournis par exemple par le module time...
>>> import sched >>> import time >>> programmateur = sched.scheduler(time.time, time.sleep)
Pour spécifier qu'un événement doit être lancé après un certain temps d'attente, on utilise la méthode enter, comme suit
programmateur.enter(délais, priorité, événement, arguments)
où :
Par exemple,
>>> import sched >>> import time >>> programmateur = sched.scheduler(time.time, time.sleep) >>> def print_event(nom): ... print "Evenement : ",time.time(), nom ... >>> programmateur.enter(20, 1, print_event, ('premier',)) (1225817485.7499959, 1, <function print_event at 0x834f5a4>, ('premier',)) >>> programmateur.enter(30, 1, print_event, ('premier',)) (1225817498.9043729, 1, <function print_event at 0x834f5a4>, ('premier',)) >>> programmateur.run() Evenement : 1225817485.75 premier Evenement : 1225817498.91 premier
Le premier événement a été lancé au bout de 20 secondes, et le deuxième au bout de 30 secondes.
L'appel à la méthode run() bloque la main jusqu'à ce que tous les événements se soient écoulés.
Supposons que l'on ait :
Alors $Y$ sera lancé immédiatement après que $X$ ait rendu la main, et le retard sera éventuellement rattrapé, au fur et à mesure que les événements programmés s'exécutent.
La méthode enterabs se comporte comme enter, sauf que le premier argument n'est plus le délais à attendre à partir du lancer de la programmation, mais l'heure absolue :
>>> maintenant = time.time() >>> programmateur.enterabs(maintenant+10, 1, print_event,('top',)) (1225817938.123019, 1, <function print_event at 0x834f5a4>, ('top',)) >>> programmateur.run() Evenement : 1225817938.13 top
L'événement s'est bien déroulé au moment souhaité.
Le retour des méthodes enter() et enterabs contient une référence à l'événement programmé, que l'on peut utiliser pour annuler ledit événement, une fois le programme lancé.
L'exécution des événements programmés s'effectue dans un thread. Si l'on souhaite ainsi pouvoir annuler un événement donné, cette annulation doit se faire à partir d'un autre thread.
Illustrons ce principe général pour l'annulation, dans un programme saisi dans un éditeur de texte :
#-*-coding:utf8-*- import sched import threading import time programmateur = sched.scheduler(time.time, time.sleep) compteur = 0 def incremente(nom): global compteur print 'EVENEMENT : ', time.time(), nom compteur += 1 print 'COMPTEUR : ', compteur print 'DEPART : ', time.time() e1 = programmateur.enter(2, 1, incremente, ('E1',)) e2 = programmateur.enter(3, 1, incremente, ('E2',)) # Départ d'un thread chargé du lancement du programmateur t = threading.Thread(target=programmateur.run) t.start() # Retour dans le thread principal, et annulation de la première tâche. programmateur.cancel(e1) # Attente de la fin des tâches t.join() print 'FINAL : ', compteur
Qui donne, après exécution :
$ python toto.py DEPART : 1225892860.52 EVENEMENT : 1225892863.52 E2 COMPTEUR : 1 FINAL : 1