threads threading thread stop manager manage example python timer python-multithreading

stop - threading.timer python



Enhebrado cancelable. Temporizador en Python (4)

Inspirado por la publicación anterior. Cancelable y restablecer el temporizador en Python. Utiliza hilo
Características: inicio, parada, reinicio, función de devolución de llamada.
Entrada: Tiempo de espera, valores de sleep_chunk y callback_function.
Puede usar o heredar esta clase en cualquier otro programa. También puede pasar argumentos a la función de devolución de llamada.
El temporizador también debe responder en el medio. No solo después de completar el tiempo de sueño completo. Entonces, en lugar de usar un sueño completo, usar pequeños trozos de sueño y seguir revisando el evento en bucle.

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()

Intento escribir un método que cuente hacia abajo en un momento dado y, a menos que se proporcione un comando de reinicio, ejecutará la tarea. Pero no creo que el threading.Timer Python. La clase de temporizador permite que el temporizador sea cancelable.

import threading def countdown(action): def printText(): print ''hello!'' t = threading.Timer(5.0, printText) if (action == ''reset''): t.cancel() t.start()

Sé que el código anterior está mal de alguna manera. Agradecería una guía amable por aquí.


La clase threading.Timer tiene un método de cancel , y aunque no cancelará el hilo , impedirá que el temporizador realmente se active. Lo que sucede en realidad es que el método cancel establece un threading.Event , y el hilo que realmente ejecuta el threading.Timer verificará ese evento una vez que haya terminado de esperar y antes de que realmente ejecute la devolución de llamada.

Dicho esto, los temporizadores generalmente se implementan sin usar un hilo separado para cada uno. La mejor manera de hacerlo depende de lo que realmente está haciendo tu programa (mientras esperas este temporizador), pero cualquier cosa con un bucle de eventos, como la GUI y los marcos de red, todos tienen formas de solicitar un temporizador que esté enganchado en eventloop.


Llamarías al método cancelar después de que inicies el temporizador:

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()

Puede considerar usar un while-loop en un Thread , en lugar de usar un Timer .
Aquí hay un ejemplo apropiado de la respuesta de Nikolaus Gradwohl a otra pregunta:

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()


No estoy seguro si entiendo correctamente. ¿Quieres escribir algo como en este ejemplo?

>>> 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() >>>