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. t = threading.Thread(target=foo,args=())
  11.  
  12. t.start() # 开启一个子线程
  13. time.sleep(3) # 主线程休眠3秒
  14. print("start server successfully... at ", time.ctime()) # 在foo函数中的event.wait()后打印这句话,此时子线程被阻塞
  15. time.sleep(3) # 主线程继续休眠3秒
  16. event.set() # 将event中的标志位设置为True,foo函数中的最后一句话就被打印了。
  17. print(event.is_set())

打印结果如下:

  1. wait server... at Sun Mar 24 11:25:51 2019
  2. start server successfully... at Sun Mar 24 11:25:54 2019
  3. 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. class Worker(threading.Thread):
  19. def run(self):
  20. event.wait() # 此时Worker线程被阻塞,等待Boss线程先运行
  21. print("Worker: 命苦啊。。。at ", time.ctime())
  22.  
  23. time.sleep(1)
  24.  
  25. event.clear() # 将_flag设置为False
  26. event.wait() # 阻塞Worker线程运行,等待老板下班命令
  27.  
  28. print("Worker: oh yeah!")
  29.  
  30. if __name__ == '__main__':
  31.  
  32. event = threading.Event()
  33.  
  34. threads = []
  35.  
  36. for i in range(5):
  37. threads.append(Worker())
  38.  
  39. threads.append(Boss())
  40.  
  41. for t in threads:
  42. t.start()
  43.  
  44. # 阻塞主线程,让子线程先执行完毕
  45. for t in threads:
  46. t.join()

打印结果如下所示:

  1. BOSS: 今晚加班到2200
  2. False
  3. Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019
  4. Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019
  5. Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019
  6. Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019
  7. Worker: 命苦啊。。。at Sun Mar 24 16:56:53 2019
  8. BOSS: 22:00了,可以下班了 at Sun Mar 24 16:56:58 2019
  9. False
  10. Worker: oh yeah!
  11. Worker: oh yeah!
  12. Worker: oh yeah!
  13. Worker: oh yeah!
  14. Worker: oh yeah!
  15.  
  16. ***Repl Closed***

线程的执行过程与event传递如图所示:

由此看见,Event对象作为一个标志位,让一个线程便于控制另一个或另一些线程的执行,而控制方式就是修改标志位的布尔值。

代码参考:

https://www.cnblogs.com/lidagen/p/7252247.html

http://www.cnblogs.com/yuanchenqi/articles/6248025.html

python线程的同步事件Event的更多相关文章

  1. Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程

    Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...

  2. 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  3. 多线程面试题系列(6):经典线程同步 事件Event

    上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...

  4. 转--- 秒杀多线程第六篇 经典线程同步 事件Event

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  5. MFC线程(三):线程同步事件(event)与互斥(mutex)

    前面讲了临界区可以用来达到线程同步.而事件(event)与互斥(mutex)也同样可以做到. Win32 API中的线程事件 HANDLE hEvent = NULL; void MainTestFu ...

  6. 秒杀多线程第六篇 经典线程同步 事件Event

    原文地址:http://blog.csdn.net/morewindows/article/details/7445233 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权” ...

  7. (92)Wangdao.com_第二十五天_线程机制_H5 Web Workers 分线程任务_事件 Event

    浏览器内核 支撑浏览器运行的最核心的程序 IE 浏览器内核            Trident内核,也是俗称的IE内核Chrome 浏览器内核            统称为 Chromium 内核或 ...

  8. 《Windows内核编程》---系统线程和同步事件

    系统线程: 在驱动中生成的线程一般是系统线程,系统线程所在的进程名为“System”,用到的内核API函数是: NTSTATUS PsCreateSystemThread( OUT PHANDLE T ...

  9. Windows驱动开发之线程与同步事件

    转载请注明来源: enjoy5512的博客 : http://blog.csdn.net/enjoy5512 GitHub : https://github.com/whu-enjoy .1. 使用系 ...

随机推荐

  1. Tensorflow环境下安装Pandas

    https://blog.csdn.net/fentone/article/details/78888136

  2. git 合并冲突 取消合并

    如果有冲突,会出现MERING 使用git merge  --abort命令解决冲突

  3. pandas列操作集锦

    列操作 pandas的列操作 数据准备: 增 将两张表合并到一起 pd.concat([page_001,page_002]).reset_index(drop=True) 默认从上到下合,如果想从左 ...

  4. Python学习—基础篇之基本数据类型(二)

    Python中重要的数据结构 1.列表 2.元组 3.字典 4.集合 列表 1.创建列表 # 方式一 name = [] print(type(name)) # 执行结果 >>> & ...

  5. Node.js 薄荷网爬取

    Node.js:是一个基于前端的服务器,主要的特点:单线程,异步I/O(对这个没有了解,开发起来真的会踩很多坑),事件驱动 前言:本人主要是一个以使用.Net平台下的语言,进行开发的一个菜鸡,之前面试 ...

  6. Gulp教程之:Gulp能做什么,前端装逼为何要用它

    我们先说说 平时web开发遇到的一些场景 和 苦恼无奈的情况: JavaScript和CSS的版本问题 我们都知道 JavaScript和CSS属于静态文件,如果地址不变,浏览器会缓存这些文件,那就意 ...

  7. FPGA驱动步进电机

    步进电机 步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受 ...

  8. 完成一个Laravel项目的过程

    1.分析项目,找出项目的元素并进行建模(navicat 该工具还可以到处sql语句) 建立关系 2.安装Laravel(使用composer来安装,如果没有的话先安装composer) 3.配置虚拟主 ...

  9. 从零开始学spring cloud(六) -------- Ribbon

    一.Ribbon介绍 Ribbon就是客户端侧负责均衡实现的一种方式,那么Ribbon是什么呢? Ribbon是Netflix发布的云中间层服务开源项目,其主要功能是提供客户端侧负载均衡算法.Ribb ...

  10. IDEA中,将项目加入maven管理。

    在项目上右键->Add Framework Support Choose Maven 生成pom.xml 在<project>下配置国内仓库 <properties>&l ...