Event对象:
用于线程间的通信,某个线程需要根据其他线程的状态来判断自己的下一步操作。
Event内部定义了一个全局变量:_flag,默认为False。 当_flag = False时,会阻塞当前线程的执行;_flag = True时,当前线程会继续执行。
Event内部还定义了如下方法来操纵标志位:
- set() ——将_flag(标志位)设置为True;
- clear()——将_flag设置为False;
- is_set()——返回当前_flag的状态。等同于isSet()。
- wait()——阻塞当前线程的执行,直到_flag被设置为True。只有当_flag = False时,调用wait()才会阻塞当前线程的运行,此时wait()方法相当于pass(什么也不做)。
示例1:主线程控制子线程的执行。
1 import threading, time 2 3 event = threading.Event() 4 5 def foo(): 6 print("wait server... at ", time.ctime()) # 开启子线程t时打印这句话 7 event.wait() # 阻塞子线程的执行,此时event中的标志位为False 8 print("connect to server... at ", time.ctime()) 9 10 11 t = threading.Thread(target=foo,args=()) 12 13 t.start() # 开启一个子线程 14 time.sleep(3) # 主线程休眠3秒 15 print("start server successfully... at ", time.ctime()) # 在foo函数中的event.wait()后打印这句话,此时子线程被阻塞 16 time.sleep(3) # 主线程继续休眠3秒 17 event.set() # 将event中的标志位设置为True,foo函数中的最后一句话就被打印了。 18 print(event.is_set())
打印结果如下:
wait server... at Sun Mar 24 11:25:51 2019 start server successfully... at Sun Mar 24 11:25:54 2019 connect to server... at Sun Mar 24 11:25:57 2019
整个程序的流程如下所示:
示例2:子线程之间传递evnet
1 import threading, time 2 3 class Boss(threading.Thread): 4 5 def run(self): 6 7 print("BOSS: 今晚加班到22:00") 8 print(event.is_set()) # _flag = False 9 10 event.set() # 将_flag设置为True,Worker线程往下执行 11 time.sleep(5) 12 13 print("BOSS: 22:00了,可以下班了 at ", time.ctime()) 14 print(event.is_set()) 15 16 event.set() # 宣布下班后,将_flag设置为True,Worker线程继续执行 17 18 19 class Worker(threading.Thread): 20 def run(self): 21 event.wait() # 此时Worker线程被阻塞,等待Boss线程先运行 22 print("Worker: 命苦啊。。。at ", time.ctime()) 23 24 time.sleep(1) 25 26 event.clear() # 将_flag设置为False 27 event.wait() # 阻塞Worker线程运行,等待老板下班命令 28 29 print("Worker: oh yeah!") 30 31 32 if __name__ == '__main__': 33 34 event = threading.Event() 35 36 threads = [] 37 38 for i in range(5): 39 threads.append(Worker()) 40 41 threads.append(Boss()) 42 43 for t in threads: 44 t.start() 45 46 # 阻塞主线程,让子线程先执行完毕 47 for t in threads: 48 t.join()
打印结果如下所示:
BOSS: 今晚加班到22:00 False Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019 Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019 Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019 Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019 Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019 BOSS: 22:00了,可以下班了 at Sun Mar 24 16:56:58 2019 False Worker: oh yeah! Worker: oh yeah! Worker: oh yeah! Worker: oh yeah! Worker: oh yeah! ***Repl Closed***
线程的执行过程与event传递如图所示:
由此看见,Event对象作为一个标志位,让一个线程便于控制另一个或另一些线程的执行,而控制方式就是修改标志位的布尔值。
代码参考:
https://www.cnblogs.com/lidagen/p/7252247.html
http://www.cnblogs.com/yuanchenqi/articles/6248025.html