Уведомления

Группа в Telegram: @pythonsu

#1 Март 25, 2011 08:07:49

Kogrom
От:
Зарегистрирован: 2009-12-03
Сообщения: 160
Репутация: +  0  -
Профиль   Отправить e-mail  

Таймер

Андрей Светлов
Не нужно перезапускать поток. Это очень накладно. threding.Timer сделан на питоне - вы тоже сможете повторить.
Не думаю, что будет очень накладно, если перезапускать поток 10 раз в секунду, да и 20, а большая частота имеет мало смысла из-за погрешностей. Но согласен, что некрасиво, потому реализовал на событиях.
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
С args, kwargs возиться не стал, ибо пока не вижу смысла.

Андрей Светлов
datetime.datetime.now - classmethod
Не понял смысла этого намёка. Если это совет как заменить потоки в таймере на процессы, то такое не всегда пройдёт, ибо при использовании процессов нужна синхронная работа процессов. Прокси-объекты (например, те, что создаёт multiprocessing.Manager) дают иллюзию, что это можно преодолеть, но настоящей асинхронности они не дают.

Поправлено позже: переименовал функцию, используемую потоком таймера.



Отредактировано (Март 25, 2011 10:33:00)

Офлайн

#2 Март 25, 2011 08:48:59

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Таймер

datetime.datetime(2000, 1, 1).now() -> datetime.datetime.now(), ничего более.



Офлайн

#3 Март 25, 2011 10:28:58

Kogrom
От:
Зарегистрирован: 2009-12-03
Сообщения: 160
Репутация: +  0  -
Профиль   Отправить e-mail  

Таймер

Андрей Светлов
datetime.datetime(2000, 1, 1).now() -> datetime.datetime.now(), ничего более.
Слона то я и не заметил…
Спасибо.



Офлайн

#4 Март 25, 2011 11:05:56

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Таймер

Еще такая загогулина: на винде (и только на ней) для коротких интервалов точнее получается через time.clock() вместо time.time()



Офлайн

#5 Март 25, 2011 12:40:53

Kogrom
От:
Зарегистрирован: 2009-12-03
Сообщения: 160
Репутация: +  0  -
Профиль   Отправить e-mail  

Таймер

Думаю, “time.time() vs time.clock()” напоминает “надёжность vs точность”. Подробнее тут:
http://www.techarticles.zeromu.net/programming/keeping-track-of-elapsed-time-in-python/

Можно наворотить что-то гибридное, но пока меня устраивает точность, которую обеспечивает time.time() в моей ОС.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version