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的gevent框架的入门教程
Apr 29 Python
解读! Python在人工智能中的作用
Nov 14 Python
分享一个简单的python读写文件脚本
Nov 25 Python
Python爬虫实例扒取2345天气预报
Mar 04 Python
Python zip()函数用法实例分析
Mar 17 Python
使用NumPy和pandas对CSV文件进行写操作的实例
Jun 14 Python
flask session组件的使用示例
Dec 25 Python
浅谈Pandas Series 和 Numpy array中的相同点
Jun 28 Python
python3 常见解密加密算法实例分析【base64、MD5等】
Dec 19 Python
Django重设Admin密码过程解析
Feb 10 Python
Pytorch中.new()的作用详解
Feb 18 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
Mar 10 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中的生成XML文件的4种方法分享
2012/10/06 PHP
ini_set的用法介绍
2014/01/07 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
2014/06/30 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
javascript 面向对象继承
2009/11/26 Javascript
jQuery结合PHP+MySQL实现二级联动下拉列表[实例]
2011/11/15 Javascript
用JSON做数据传输格式中的一些问题总结
2011/12/21 Javascript
javascript实现十六进制颜色值(HEX)和RGB格式相互转换
2014/06/20 Javascript
Javascript实现获取窗口的大小和位置代码分享
2014/12/04 Javascript
angularJS 如何读写缓冲的方法(推荐)
2016/08/06 Javascript
jquery表单插件form使用方法详解
2017/01/20 Javascript
Spring shiro + bootstrap + jquery.validate 实现登录、注册功能
2017/06/02 jQuery
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
vue项目中v-model父子组件通信的实现详解
2017/12/10 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
2018/10/08 Javascript
细述Javascript的加法运算符的具体使用
2019/10/18 Javascript
Vue.js 中制作自定义选择组件的代码附演示demo
2020/02/28 Javascript
Python检测字符串中是否包含某字符集合中的字符
2015/05/21 Python
Python的多态性实例分析
2015/07/07 Python
python 获取list特定元素下标的实例讲解
2018/04/09 Python
解决Python运行文件出现out of memory框的问题
2018/12/03 Python
python实现证件照换底功能
2019/08/20 Python
解决pytorch报错:AssertionError: Invalid device id的问题
2020/01/10 Python
Python @property原理解析和用法实例
2020/02/11 Python
在python中logger setlevel没有生效的解决
2020/02/21 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
new修饰符是起什么作用
2015/06/28 面试题
网络教育毕业生自我鉴定
2013/10/10 职场文书
酒吧员工的岗位职责
2013/11/26 职场文书
实习评语
2013/12/16 职场文书
机关道德讲堂实施方案
2014/03/15 职场文书
抄袭同学作业检讨书1000字
2014/11/20 职场文书
业务员岗位职责
2015/02/03 职场文书
python接口测试返回数据为字典取值方式
2022/02/12 Python
Mysql分析设计表主键为何不用uuid
2022/03/31 MySQL