有没有办法在Python中扩展threading.Timer

3 投票
3 回答
2219 浏览
提问于 2025-04-18 16:05

关于 threading.Timer 对象,有没有办法在调用 start 方法后更新定时器的时间?

比如说:

timer = threading.Timer(5, function)
timer.start()
#after calling start method, i want to extend the timer time before expired.

我查看了 threading.Timer 的文档,发现没有办法。

所以我是不是得先调用 cancel 方法,然后再调用 start 方法?

3 个回答

0

取消当前的计时器,然后重新开始一个新的计时器。

1

没有人发代码示例,所以我想我也可以来发一个。我按照上面的建议做了,先取消定时器,然后再重新启动。使用这个方法,最开始会每5秒打印一次“hello world”,然后在重新运行时,会把这个频率提高到每秒一次。它还打印了一些时间戳,用来展示并发的效果。

import time
import threading

def printit(runs):
  if runs == 1:
      timer = threading.Timer(5.0, printit, [runs])
      timer.start()
      runs += 1
  else:
      timer = threading.Timer(1.0, printit, [runs])
      timer.start()

  print("Hello, World!")
  timer.cancel()
  timer = threading.Timer(1.0, printit, [runs])
  timer.start()

if __name__ == '__main__':
    runs = 1
    printit(runs)
    now = time.time()
    print('The current time is: ' + str(now))
    time.sleep(7)
    current = time.time()
    print('The current time is: ' + str(current))
3

Timer对象其实非常简单:

def Timer(*args, **kwargs):
    return _Timer(*args, **kwargs)

class _Timer(Thread):
    """Call a function after a specified number of seconds:

    t = Timer(30.0, f, args=[], kwargs={})
    t.start()
    t.cancel() # stop the timer's action if it's still waiting
    """

    def __init__(self, interval, function, args=[], kwargs={}):
        Thread.__init__(self)
        self.interval = interval
        self.function = function
        self.args = args
        self.kwargs = kwargs
        self.finished = Event()

    def cancel(self):
        """Stop the timer if it hasn't finished yet"""
        self.finished.set()

    def run(self):
        self.finished.wait(self.interval)
        if not self.finished.is_set():
            self.function(*self.args, **self.kwargs)
        self.finished.set()

它只是通过在一个threading.Event对象上调用wait方法并设置超时时间来等待,然后要么执行你提供的方法,要么在调用cancel时退出。如果你想的话,可以自己实现一个支持延长等待时间的Timer版本,但默认的这个是没有这个功能的。

撰写回答