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