Андрей СветловНе думаю, что будет очень накладно, если перезапускать поток 10 раз в секунду, да и 20, а большая частота имеет мало смысла из-за погрешностей. Но согласен, что некрасиво, потому реализовал на событиях.
Не нужно перезапускать поток. Это очень накладно. threding.Timer сделан на питоне - вы тоже сможете повторить.
class Timer:
def __init__(self, function):
self._func = function
self._finished = threading.Event()
self._timer = None
def start(self, period, startWithJerk=False):
if not self.is_running():
self._currentTime = time.time()
if startWithJerk: self._func()
self._period = period
self._finished.clear()
self._timer = threading.Thread(target=self._timer_func)
self._timer.daemon = True
self._timer.start()
def _calc_period(self):
self._currentTime += self._period
period = self._period - (time.time() - self._currentTime)
while period <= 0:
period += self._period
return period
def _timer_func(self):
while True:
self._finished.wait(self._calc_period())
if self._finished.is_set():
break
else:
self._func()
def is_running(self):
return self._timer != None
def stop(self):
if self.is_running():
self._finished.set()
self._timer.join()
self._timer = None
Андрей СветловНе понял смысла этого намёка. Если это совет как заменить потоки в таймере на процессы, то такое не всегда пройдёт, ибо при использовании процессов нужна синхронная работа процессов. Прокси-объекты (например, те, что создаёт multiprocessing.Manager) дают иллюзию, что это можно преодолеть, но настоящей асинхронности они не дают.
datetime.datetime.now - classmethod
Поправлено позже: переименовал функцию, используемую потоком таймера.