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元组拆包和具名元组解析实例详解
Mar 26 Python
用python写扫雷游戏实例代码分享
May 27 Python
python中使用print输出中文的方法
Jul 16 Python
Python中创建二维数组
Oct 17 Python
python实战串口助手_解决8串口多个发送的问题
Jun 12 Python
django创建简单的页面响应实例教程
Sep 06 Python
Pytorch 保存模型生成图片方式
Jan 10 Python
Python openpyxl模块原理及用法解析
Jan 19 Python
通过实例简单了解python yield使用方法
Aug 06 Python
Python join()函数原理及使用方法
Nov 14 Python
python os.rename实例用法详解
Dec 06 Python
Selenium执行完毕未关闭chromedriver/geckodriver进程的解决办法(java版+python版)
Dec 07 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
利用PHP实现智能文件类型检测的实现代码
2011/08/02 PHP
javascript 一些用法小结
2009/09/11 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
javascript获取select的当前值示例代码(兼容IE/Firefox/Opera/Chrome)
2013/12/17 Javascript
JS实现判断碰撞的方法
2015/02/11 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
JQuery学习总结【一】
2016/12/01 Javascript
JavaScript原生节点操作小结
2017/01/17 Javascript
JavaScript无缝滚动效果的实例代码
2017/03/27 Javascript
详谈js模块化规范
2017/07/07 Javascript
在ABP框架中使用BootstrapTable组件的方法
2017/07/31 Javascript
ES6 javascript的异步操作实例详解
2017/10/30 Javascript
ant-design-vue 实现表格内部字段验证功能
2019/12/16 Javascript
javascript 易错知识点实例小结
2020/04/25 Javascript
如何在postman中添加cookie信息步骤解析
2020/06/30 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
2020/11/16 Javascript
[04:36]DOTA2国际邀请赛 ti3精彩集锦
2013/08/19 DOTA
python实现监控windows服务并自动启动服务示例
2014/04/17 Python
Python贪吃蛇游戏编写代码
2020/10/26 Python
python使用Pycharm创建一个Django项目
2018/03/05 Python
python实现excel读写数据
2021/03/02 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
2018/08/22 Python
浅谈pycharm出现卡顿的解决方法
2018/12/03 Python
python中threading开启关闭线程操作
2020/05/02 Python
Python导入数值型Excel数据并生成矩阵操作
2020/06/09 Python
pycharm 如何取消连按两下shift出现的全局搜索
2021/01/15 Python
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
专科毕业生求职简历的自我评价
2013/10/12 职场文书
个人自我鉴定写法
2013/11/30 职场文书
共筑中国梦演讲稿
2014/04/23 职场文书
社区先进事迹材料
2014/05/19 职场文书
预防煤气中毒方案
2014/06/16 职场文书
服装仓管员岗位职责
2014/06/17 职场文书
文明单位创建材料
2014/12/24 职场文书
世界水日宣传活动总结
2015/02/09 职场文书
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang