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 isinstance判断对象类型
Sep 06 Python
python 队列详解及实例代码
Oct 18 Python
python 迭代器和iter()函数详解及实例
Mar 21 Python
Python自动发邮件脚本
Mar 31 Python
Pycharm无法使用已经安装Selenium的解决方法
Oct 13 Python
python 切换root 执行命令的方法
Jan 19 Python
tensorflow 实现打印pb模型的所有节点
Jan 23 Python
python实现时间序列自相关图(acf)、偏自相关图(pacf)教程
Jun 03 Python
python模块如何查看
Jun 16 Python
pycharm激活码免费分享适用最新pycharm2020.2.3永久激活
Nov 25 Python
python实战之一步一步教你绘制小猪佩奇
Apr 22 Python
python机器学习创建基于规则聊天机器人过程示例详解
Nov 02 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
jq的get传参数在utf-8中乱码问题的解决php版
2008/07/23 PHP
php在字符串中查找另一个字符串
2008/11/19 PHP
常用PHP框架功能对照表
2014/10/23 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
2017/09/16 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
js 创建书签小工具之理论
2011/02/25 Javascript
File, FileReader 和 Ajax 文件上传实例分析(php)
2011/04/27 Javascript
中文字符串截取的js函数代码
2013/04/17 Javascript
DOM基础教程之使用DOM设置文本框
2015/01/20 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
js导出excel文件的简洁方法(推荐)
2016/11/02 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
ES6中Symbol类型用法实例详解
2017/04/06 Javascript
Js自定义多选框效果的实例代码
2017/07/05 Javascript
vue中@change兼容问题详解
2019/10/25 Javascript
简单掌握Python的Collections模块中counter结构的用法
2016/07/07 Python
由浅入深讲解python中的yield与generator
2017/04/05 Python
pymongo中group by的操作方法教程
2019/03/22 Python
一篇文章弄懂Python中所有数组数据类型
2019/06/23 Python
pycharm配置当鼠标悬停时快速提示方法参数
2019/07/31 Python
python生成随机红包的实例写法
2019/09/02 Python
CSS3中31种选择器使用方法教程
2013/12/05 HTML / CSS
推荐WEB开发者最佳HTML5和CSS3代码生成器
2015/11/24 HTML / CSS
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
香港最大的洋酒零售连锁店:屈臣氏酒窖(Watson’s Wine)
2018/12/10 全球购物
高中生校园生活自我评价
2013/09/19 职场文书
工程管理造价应届生求职信
2013/11/13 职场文书
滞留工资返还协议书
2014/10/19 职场文书
整改落实自查报告
2014/11/05 职场文书
研究生毕业论文导师评语
2014/12/31 职场文书
综合素质评价思想道德自我评价
2015/03/09 职场文书
中标通知书
2015/04/17 职场文书
本科毕业论文致谢词
2015/05/14 职场文书
CDPR谈《巫师》新作用虚幻5原因 称不会为Epic独占
2022/04/06 其他游戏
ant design vue的form表单取值方法
2022/06/01 Vue.js