threading.Timer 的作用
官方给的定义是:
"""Call a function after a specified number of seconds:
t = Timer(30.0, f, args=None, kwargs=None)
t.start()
t.cancel() # stop the timer's action if it's still waiting
"""
意思是:
在一个特定的秒数之后调用一个函数, 使用方法是创建一个 Timer 实例, 然后 start() 启动线程, 如果在线程调用传入的函数之前可以使用 cancel 进行取消.
threading.Timer 源码分析
- 1 class Timer(Thread): # 继承自 Thread 类
- 2 """Call a function after a specified number of seconds:
- 3
- 4 t = Timer(30.0, f, args=None, kwargs=None)
- 5 t.start()
- 6 t.cancel() # stop the timer's action if it's still waiting
- 7
- 8 """
- 9
- 10 def __init__(self, interval, function, args=None, kwargs=None): # 初始化的时候传参是延迟时间, 调用的函数, 函数的可变位置参数, 函数的可变关键字参数
- 11 Thread.__init__(self) # 调用 Thread 类初始化配置实例
- 12 self.interval = interval # 在使用 Thread 类初始化配置实例之后再额外的增加 interval 属性
- 13 self.function = function # 同理再额外的增加 function 属性
- 14 self.args = args if args is not None else [] # 如果 args 不是空的话就使用 args, 如果是空就给一个空 list
- 15 self.kwargs = kwargs if kwargs is not None else {} # 同理, kwargs 不是空的就是 kwargs, 如果是空就给一个空字典
- 16 self.finished = Event() # 再添加一个属性 finished, 是一个 Event 类的实例, 这里知道 Event 类的实例用法就知道它在这里要怎么用了
- 17
- 18 def cancel(self):
- """如果 finished 属性还没有被 set, 即函数 function 还没有被调用的之前阻止, 因为下面函数调用之前会判断 finished 是否被 set 了, 所以这里赶在调用之前注定 set 就能够阻止后面的调用."""
- 19 """Stop the timer if it hasn't finished yet."""
- 20 self.finished.set()
- 21
- 22 def run(self): # 继承自 Thread 类, 并且重写了 Thread 类, 我们分析 Thread 类的源码会发现, start() 方法会主动调用 self.run(),
- # 我们 Timer 类没有实现 start() 方法, 这样 Timer 类实例在执行 start() 的时候会跑到父类 Thread 上, 然后调用父类的 start,
- # 在父类的 start() 方法中会有一句 self.run() 来调用工作线程中的函数, 这里 self 是 Timer 的实例, 所以, 这里可以重写 run 就可以设定 run 的时间了.
- 23 self.finished.wait(self.interval) # 这里使用 Event 类的实例的 wait 方法, 等待了我们设定的 self.interval 时间, 然后关键点是下面一句
- 24 if not self.finished.is_set(): # 这一句是关键点, 检查一下是否被 set 了, 如果没有被 set 了就调用传入的函数, 如果被 set 了有两种情况:
- # 第一种情况是在 self.finished.wait(self.interval) 的期间, 我们调用 cancel 主动提前 set 了;
- # 第二种情况是已经 start() 过一次了, 这里就不能再进行 start 了这样就和父类的保持了一致: 即一个线程只能够 start 一次
- 25 self.function(*self.args, **self.kwargs)
- 26 self.finished.set() # 调用完成后 set, 即便之前已经被 set 了, 这里还可以被 set, 因为 Event 实例可以被 set 多次.
来源: http://www.bubuko.com/infodetail-3281492.html