Python中使用threading.Event协调线程的运行详解


Posted in Python onMay 02, 2020

threading.Event机制类似于一个线程向其它多个线程发号施令的模式,其它线程都会持有一个threading.Event的对象,这些线程都会等待这个事件的“发生”,如果此事件一直不发生,那么这些线程将会阻塞,直至事件的“发生”。

对此,我们可以考虑一种应用场景(仅仅作为说明),例如,我们有多个线程从Redis队列中读取数据来处理,这些线程都要尝试去连接Redis的服务,一般情况下,如果Redis连接不成功,在各个线程的代码中,都会去尝试重新连接。

如果我们想要在启动时确保Redis服务正常,才让那些工作线程去连接Redis服务器,那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作:

主线程中会去尝试连接Redis服务,如果正常的话,触发事件,各工作线程会尝试连接Redis服务。

为此,我们可以写下如下的程序:

import threading
import time
import logging
 
logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)
 
def worker(event):
  logging.debug('Waiting for redis ready...')
  event.wait()
  logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())
  time.sleep(1)
 
readis_ready = threading.Event()
t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')
t1.start()
 
t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')
t2.start()
 
logging.debug('first of all, check redis server, make sure it is OK, and then trigger the redis ready event')
time.sleep(3) # simulate the check progress 
readis_ready.set()

运行这个程序:

(t1    ) Waiting for redis ready...
(t2    ) Waiting for redis ready...
(MainThread) first of all, check redis server, make sure it is OK, and then trigger the redis ready event
(t2    ) redis ready, and connect to redis server and do some work [Wed Nov 5 12:45:03 2014]
(t1    ) redis ready, and connect to redis server and do some work [Wed Nov 5 12:45:03 2014]

t1和t2线程开始的时候都阻塞在等待redis服务器启动的地方,一旦主线程确定了redis服务器已经正常启动,那么会触发redis_ready事件,各个工作线程就会去连接redis去做相应的工作。

threading.Event的wait方法还接受一个超时参数,默认情况下如果事件一直没有发生,wait方法会一直阻塞下去,而加入这个超时参数之后,如果阻塞时间超过这个参数设定的值之后,wait方法会返回。

对应于上面的应用场景,如果Redis服务器一致没有启动,我们希望子线程能够打印一些日志来不断地提醒我们当前没有一个可以连接的Redis服务,我们就可以通过设置这个超时参数来达成这样的目的:

import threading
import time
import logging
 
logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)
 
def worker(event):
  while not event.is_set():
    logging.debug('Waiting for redis ready...')
    event.wait(1)
  logging.debug('redis ready, and connect to redis server and do some work [%s]', time.ctime())
  time.sleep(1)
 
readis_ready = threading.Event()
t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')
t1.start()
 
t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')
t2.start()
 
logging.debug('first of all, check redis server, make sure it is OK, and then trigger the redis ready event')
time.sleep(3) # simulate the check progress 
readis_ready.set()

与前面的无限阻塞版本唯一的不同就是,我们在工作线程中加入了一个while循环,直到redis_ready事件触发之后才会结束循环,wait方法调用会在1秒的超时后返回,这样,我们就可以看到各个工作线程在系统启动的时候等待redis_ready的同时,会记录一些状态信息。

以下是这个程序的运行结果:

(t1    ) Waiting for redis ready...
(t2    ) Waiting for redis ready...
(MainThread) first of all, check redis server, make sure it is OK, and then trigger the redis ready event
(t2    ) Waiting for redis ready...
(t1    ) Waiting for redis ready...
(t2    ) Waiting for redis ready...
(t1    ) Waiting for redis ready...
(t2    ) redis ready, and connect to redis server and do some work [Wed Nov 5 13:55:46 2014]
(t1    ) redis ready, and connect to redis server and do some work [Wed Nov 5 13:55:46 2014]

这样,我们就可以在等待Redis服务启动的同时,看到工作线程里正在等待的情况。

以上这篇Python中使用threading.Event协调线程的运行详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python操作MongoDB基础知识
Nov 01 Python
python实现逆波兰计算表达式实例详解
May 06 Python
python使用WMI检测windows系统信息、硬盘信息、网卡信息的方法
May 15 Python
Centos Python2 升级到Python3的简单实现
Jun 21 Python
Python实现对百度云的文件上传(实例讲解)
Oct 21 Python
Python 实现还原已撤回的微信消息
Jun 18 Python
python单例模式的多种实现方法
Jul 26 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
Feb 11 Python
python统计文章中单词出现次数实例
Feb 27 Python
浅析PyCharm 的初始设置(知道)
Oct 12 Python
Python调用JavaScript代码的方法
Oct 27 Python
Python self用法详解
Nov 28 Python
浅谈Python3多线程之间的执行顺序问题
May 02 #Python
python继承threading.Thread实现有返回值的子类实例
May 02 #Python
Python3-异步进程回调函数(callback())介绍
May 02 #Python
浅谈Python中threading join和setDaemon用法及区别说明
May 02 #Python
判断Threading.start新线程是否执行完毕的实例
May 02 #Python
python中threading开启关闭线程操作
May 02 #Python
浅谈python3打包与拆包在函数的应用详解
May 02 #Python
You might like
PDO版本问题 Invalid parameter number: no parameters were bound
2013/01/06 PHP
基于initPHP的框架介绍
2013/04/18 PHP
腾讯CMEM的PHP扩展编译安装方法
2015/09/25 PHP
phalcon model在插入或更新时会自动验证非空字段的解决办法
2016/12/29 PHP
yii2利用自带UploadedFile实现上传图片的示例
2017/02/16 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
json的定义、标准格式及json字符串检验
2014/05/11 Javascript
JQuery页面地址处理插件jqURL详解
2015/05/03 Javascript
jQuery实现浮动层随浏览器滚动条滚动的方法
2015/09/22 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
js表单验证实例讲解
2016/03/31 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
JavaScript设计模式之享元模式实例详解
2019/01/17 Javascript
为Python程序添加图形化界面的教程
2015/04/29 Python
纯python实现机器学习之kNN算法示例
2018/03/01 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
Python 继承,重写,super()调用父类方法操作示例
2019/09/29 Python
python opencv根据颜色进行目标检测的方法示例
2020/01/15 Python
python获取响应某个字段值的3种实现方法
2020/04/30 Python
python3发送request请求及查看返回结果实例
2020/04/30 Python
联想新加坡官方网站:Lenovo Singapore
2017/10/24 全球购物
美国最大的在线水培用品商店:GrowersHouse.com
2018/08/14 全球购物
Urban Decay官方网站:美国化妆品品牌
2020/06/04 全球购物
C#和SQL Server的面试题
2016/08/12 面试题
物流管理专业自荐信
2014/06/23 职场文书
幼儿老师求职信
2014/06/30 职场文书
商务邀请函
2015/01/30 职场文书
企业财务经理岗位职责
2015/04/08 职场文书
党员违纪检讨书
2015/05/05 职场文书
长征观后感
2015/06/09 职场文书
2015年小学语文教师工作总结
2015/10/23 职场文书
2019销售早会主持词
2019/06/27 职场文书
MySQL分库分表与分区的入门指南
2021/04/22 MySQL
JavaScript如何利用Promise控制并发请求个数
2021/05/14 Javascript
OpenCV-Python实现轮廓的特征值
2021/06/09 Python