Постоянное выполнение цикла в countdown
, безусловно, нежелательно.Было бы полезно оставить его в спящем режиме на более длительные периоды, так как это приостанавливает вызывающий поток и позволяет использовать циклы, которые он использовал для других задач.
Однако я также не вижу, что это слишком пагубно для вашего общего состояния.производительность.
Тем не менее, я рекомендую использовать Timer
из модуля threading
.
Этот класс представляет действие, которое должно выполняться только послеопределенное количество времени прошло - таймер.Timer
является подклассом Thread
[...]
Timer.cancel()
позволяет остановить таймер, пока он находится в состоянии ожидания (хотя это может бытьвызывается впоследствии без какого-либо эффекта).Это позволяет завершить метод run
до истечения интервала времени ожидания, а self.timedout
остаться ложным, если не истекло время ожидания.
class Runner:
def __init__(self):
self.timedout = False
self.timeout_sec = 60
def _set_timeout(self):
self.timedout = True
def run(self):
timer = Timer(self.timeout_sec, function=self._set_timeout)
timer.start()
# do various things, call the chain of methods...
timer.cancel()
Можно избавиться от _set_timeout
метод с использованием lambda
.Хотя это кажется немного неуклюжим.Поскольку тело лямбда-выражения должно быть выражением, а var = True
- выражением, необходимо использовать setattr
и передать экземпляр в лямбду:
timer = Timer(self.timeout_sec, function=lambda inst: setattr(inst, "timedout", True), args=(self,))
Другой вариант - сделать self.timedout
an Event
и вызовите его метод set()
, чтобы сообщить об истечении времени ожидания.
self.timedout = Event()
[...]
timer = Timer(self.timeout_sec, function=lambda to: to.set(), args=(self.timedout,))
Проверка того, произошло ли событие тайм-аута, будет выполняться черезEvent.is_set()
:
if self.timedout.is_set():
[...]