Created
February 11, 2018 00:28
-
-
Save TomFaulkner/6a790051701c291f53c07de9192c7fb6 to your computer and use it in GitHub Desktop.
Python Perpetual (Repeating) Timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
PerpetualTimer: Run a function every x seconds until PerpetualTimer.cancel(). | |
Source, with some modificiations: | |
https://stackoverflow.com/questions/12435211/python-threading-timer-repeat-function-every-n-seconds | |
Example usage: | |
def printer(): | |
print('ipsem lorem') | |
t = PerpetualTimer(3, printer) | |
t.start() | |
time.sleep(8) | |
t.cancel() | |
There is an issue of concern with this code. If the interval is relatively low | |
compared to the time it takes the handler_function to run much of the time will | |
be spent in the blocking function and .cancel will not work. Cancel will only | |
work while a timer is active and nothing is going on. | |
For example, if seconds=30 and handler_function is blocking for 10 seconds the | |
Timer will start for 30 seconds, then the handler_function will block for | |
twenty. The Timer, which is not blocked, will execute again 20 seconds after | |
the blocking function is done. | |
One potential solution is to have handler_function be a function that spawns a | |
thread. | |
""" | |
import time | |
from threading import Timer | |
class PerpetualTimer: | |
"""A Timer class that does not stop, unless you want it to.""" | |
def __init__(self, seconds, target): | |
self._should_continue = False | |
self.is_running = False | |
self.seconds = seconds | |
self.target = target | |
self.thread = None | |
def _handle_target(self): | |
self.is_running = True | |
self.target() | |
self.is_running = False | |
print('handled target') | |
self._start_timer() | |
def _start_timer(self): | |
# Code could have been running when cancel was called. | |
if self._should_continue: | |
self.thread = Timer(self.seconds, self._handle_target) | |
self.thread.start() | |
def start(self): | |
if not self._should_continue and not self.is_running: | |
self._should_continue = True | |
self._start_timer() | |
def cancel(self): | |
if self.thread is not None: | |
# Just in case thread is running and cancel fails. | |
self._should_continue = False | |
self.thread.cancel() | |
if __name__ == '__main__': | |
# Example usage: | |
def printer(): | |
print('ipsem lorem') | |
t = PerpetualTimer(3, printer) | |
t.start() | |
time.sleep(8) | |
t.cancel() |
Assuming this is the actual code, you spelled cancel
as "calcel."
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
y try cancel the thread and i cant
from threading import Timer,Thread,Event
import time
import RPi.GPIO as GPIO
import time
class perpetualTimer():
def init(self,t,hFunction):
self.t=t
self.hFunction = hFunction
self.thread = Timer(self.t,self.handle_function)
def handle_function(self):
self.hFunction()
self.thread = Timer(self.t,self.handle_function)
self.thread.start()
def start(self):
self.thread.start()
def cancel(self):
self.thread.cancel()
def apagar():
print ('ipsem lorem')
def encender():
s.calcel()
t.calcel()
t = perpetualTimer(0.05, apagar)
s = perpetualTimer(5, encender)
t.start()
s.start()
generate this error
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 1073, in run
self.function(*self.args, **self.kwargs)
File "hilo_infinito_fallo.py", line 15, in handle_function
self.hFunction()
File "hilo_infinito_fallo.py", line 29, in encender
s.calcel()
AttributeError: perpetualTimer instance has no attribute 'calcel'
can you help me?
thank