Timer继承子Thread类,是Thread的子类,也是线程类,具有线程的能力和特征。这个类用来定义多久执行一个函数。
它的实例是能够延迟执行目标函数的线程,在真正执行目标函数之前,都可以cancel它。
Timer源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Timer(Thread): def __init__( self , interval, function, args = None , kwargs = None ): Thread.__init__( self ) self .interval = interval self .function = function self .args = args if args is not None else [] self .kwargs = kwargs if kwargs is not None else {} 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 () |
Timer类使用方法与Thread定义子线程一样,interval传入间隔时间,function传入线程执行的函数,args和kwargs传入函数的参数。
提前cancel:
1
2
3
4
5
6
7
8
9
|
import threading import time def add(x,y): print (x + y) t = threading.Timer( 10 ,add,args = ( 4 , 5 )) t.start() time.sleep( 2 ) t.cancel() print ( "===end===" ) |
运行结果:
===end===
start方法执行之后,Timer对象会处于等待状态,等待10秒之后会执行add函数。同时,在执行add函数之前的等待阶段,主线程使用了子线程的cancel方法,就会跳过执行函数结束。
使用event 事件实现Timer计时器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import threading import logging import time logging.basicConfig(level = logging.INFO) # class MyTimer(threading.Thread): class MyTimer: def __init__( self ,interval,fn,args = None ): self .interval = interval self .fn = fn self .args = args self .event = threading.Event() def start( self ): threading.Thread(target = self .__do).start() def cancel( self ): self .event. set () def __do( self ): self .event.wait( self .interval) if not self .event.is_set(): self .fn( * self .args) def add(x,y): logging.warning(x + y) t = MyTimer( 5 ,add,( 4 , 5 )) t.start() # time.sleep(2) # t.cancel() |
运行结果:
WARNING:root:9
Event事件,是线程间通信机制中最简单的实现,使用一个内部的标记flag,通过flag的True或False的变化来进行操作。
Event源码:
class Event:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
def __init__( self ): self ._cond = Condition(Lock()) self ._flag = False def _reset_internal_locks( self ): self ._cond.__init__(Lock()) def is_set( self ): return self ._flag isSet = is_set def set ( self ): with self ._cond: self ._flag = True self ._cond.notify_all() def clear( self ): with self ._cond: self ._flag = False def wait( self , timeout = None ): with self ._cond: signaled = self ._flag if not signaled: signaled = self ._cond.wait(timeout) return signaled |
Event 方法:
•set() flag设置为True
•clear() flag设置为False
•is_set() flag是否为True,返回布尔值
•wait(timeout=None) 设置等待flag变为True的时长,None为无限等待。等到了返回True,未等到超时了就返回False。
举例:
老板雇佣了一个工人,让他生产杯子,老板一直等着工人,直到生产了10个杯子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import threading import logging import time logging.basicConfig(level = logging.INFO) cups = [] event = threading.Event() #event对象 def boss(e:threading.Event): if e.wait( 30 ): #最多等待30秒 logging.info( 'Good job.' ) def worker(n,e:threading.Event): while True : time.sleep( 0.5 ) cups.append( 1 ) logging.info( 'make 1' ) if len (cups) > = n: logging.info( 'I finished my job. {}' . format ( len (cups))) e. set () #flag设置为True break b = threading.Thread(target = boss,name = 'boos' ,args = (event,)) w = threading.Thread(target = worker,args = ( 10 ,event)) w.start() b.start() |
运行结果:
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:make 1
INFO:root:I finished my job. 10
INFO:root:Good job.
老板和工人使用同一个Event对象的标记flag。
老板wait()设置为最多等待30秒,等待flag变为True,工人在做够10杯子时,将flag设置为True,工人必须在30秒之内没有做好杯子。
wait的使用:
1
2
3
4
5
6
7
8
9
10
11
12
|
import threading import logging logging.basicConfig(level = logging.INFO) def do(event:threading.Event,interval: int ): while not event.wait(interval): # not event.wait(1) = True logging.info( 'To do sth.' ) e = threading.Event() t = threading.Thread(target = do,args = (e, 1 )) t.start() e.wait( 10 ) # 也可以使用time.sleep(10) e. set () print ( 'Man Exit.' ) |
运行结果:
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
INFO:root:To do sth.
Man Exit.
wait与sleep的区别是:wait会主动让出时间片,其它线程可以被调度,而sleep会占用时间片不让出。
小结:
Timer定时器继承自Thread类,也是线程类。它的作用是等待n秒钟之后执行某个目标函数,可以使用cancel提前取消。
Event事件是通过True和False维护一个flag标记值,通过这个标记的值来决定做某事,wait()方法可以设置最长等待flag设置为Ture的时长,超时还未设置为True就返回False。
PS:下面看下python之定时器Timer
timer类
Timer(定时器)是Thread的派生类,用于在指定时间后调用一个方法。
构造方法:
1
2
3
4
|
Timer(interval, function, args = [], kwargs = {}) interval: 指定的时间 function: 要执行的方法 args / kwargs: 方法的参数 |
实例方法:
Timer从Thread派生,没有增加实例方法。
例子一:
1
2
3
4
5
6
|
# encoding: UTF-8 import threading def func(): print 'hello timer!' timer = threading.Timer( 5 , func) timer.start() |
线程延迟5秒后执行。
总结
以上所述是小编给大家介绍的详解Python 多线程 Timer定时器/延迟执行、Event事件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
原文链接:https://www.cnblogs.com/i-honey/p/8051680.html