J'essaie d'écrire une méthode qui compte à rebours à un moment donné et à moins qu'une commande de redémarrage ne soit donnée, il exécutera la tâche. Mais je ne pense pas que la classe Python threading.Timer
permette l'annulation du minuteur.
import threading
def countdown(action):
def printText():
print 'hello!'
t = threading.Timer(5.0, printText)
if (action == 'reset'):
t.cancel()
t.start()
Je sais que le code ci-dessus est faux en quelque sorte. J'apprécierais des conseils aimables par ici.
Vous appelez la méthode cancel après avoir démarré le chronomètre:
import time
import threading
def hello():
print "hello, world"
time.sleep(2)
t = threading.Timer(3.0, hello)
t.start()
var = 'something'
if var == 'something':
t.cancel()
Vous pourriez envisager d'utiliser une boucle while sur un Thread , au lieu d'utiliser un Timer.
Voici un exemple approprié de Nikolaus Gradwohl's answer à une autre question:
import threading
import time
class TimerClass(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
self.count = 10
def run(self):
while self.count > 0 and not self.event.is_set():
print self.count
self.count -= 1
self.event.wait(1)
def stop(self):
self.event.set()
tmr = TimerClass()
tmr.start()
time.sleep(3)
tmr.stop()
Je ne suis pas sûr de bien comprendre. Voulez-vous écrire quelque chose comme dans cet exemple?
>>> import threading
>>> t = None
>>>
>>> def sayHello():
... global t
... print "Hello!"
... t = threading.Timer(0.5, sayHello)
... t.start()
...
>>> sayHello()
Hello!
Hello!
Hello!
Hello!
Hello!
>>> t.cancel()
>>>
La classe threading.Timer
fait a une méthode cancel
et, bien qu'elle n'annule pas le thread, elle empêchera le chronomètre de se déclencher. En réalité, la méthode cancel
définit un threading.Event
et le thread qui exécute le threading.Timer
vérifiera cet événement une fois l'attente terminée et avant l'exécution du rappel.
Cela dit, les timers sont généralement implémentés sans en utilisant un thread distinct pour chacun. La meilleure façon de le faire dépend de ce que votre programme est en train de faire (en attendant ce minuteur), mais tout ce qui a une boucle d’événement, telle que les interfaces graphiques et réseau, permet de demander un minuteur connecté au eventloop.
Inspiré par le message ci-dessus . Annulable et réinitialisation du minuteur en Python. Il utilise du fil.
Caractéristiques: Démarrer, Arrêter, Redémarrer, fonction de rappel.
Entrée: valeurs de délai d’attente, sleep_chunk et callback_function.
Peut utiliser ou hériter de cette classe dans n’importe quel autre programme. Peut également passer des arguments à la fonction de rappel.
La minuterie devrait répondre au milieu aussi. Pas juste après la fin du temps de sommeil complet. Ainsi, au lieu d’utiliser un seul sommeil complet, utilisez de petits morceaux de sommeil et gardez l’objet de vérification en boucle.
import threading
import time
class TimerThread(threading.Thread):
def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
threading.Thread.__init__(self)
self.timeout = timeout
self.sleep_chunk = sleep_chunk
if callback == None:
self.callback = None
else:
self.callback = callback
self.callback_args = args
self.terminate_event = threading.Event()
self.start_event = threading.Event()
self.reset_event = threading.Event()
self.count = self.timeout/self.sleep_chunk
def run(self):
while not self.terminate_event.is_set():
while self.count > 0 and self.start_event.is_set():
# print self.count
# time.sleep(self.sleep_chunk)
# if self.reset_event.is_set():
if self.reset_event.wait(self.sleep_chunk): # wait for a small chunk of timeout
self.reset_event.clear()
self.count = self.timeout/self.sleep_chunk # reset
self.count -= 1
if self.count <= 0:
self.start_event.clear()
#print 'timeout. calling function...'
self.callback(*self.callback_args)
self.count = self.timeout/self.sleep_chunk #reset
def start_timer(self):
self.start_event.set()
def stop_timer(self):
self.start_event.clear()
self.count = self.timeout / self.sleep_chunk # reset
def restart_timer(self):
# reset only if timer is running. otherwise start timer afresh
if self.start_event.is_set():
self.reset_event.set()
else:
self.start_event.set()
def terminate(self):
self.terminate_event.set()
#=================================================================
def my_callback_function():
print 'timeout, do this...'
timeout = 6 # sec
sleep_chunk = .25 # sec
tmr = TimerThread(timeout, sleep_chunk, my_callback_function)
tmr.start()
quit = '0'
while True:
quit = raw_input("Proceed or quit: ")
if quit == 'q':
tmr.terminate()
tmr.join()
break
tmr.start_timer()
if raw_input("Stop ? : ") == 's':
tmr.stop_timer()
if raw_input("Restart ? : ") == 'r':
tmr.restart_timer()