Python中使用threading.Event协调线程的运行
来源:互联网 发布:美国eia原油库存数据 编辑:程序博客网 时间:2024/05/18 01:40
threading.Event机制类似于一个线程向其它多个线程发号施令的模式,其它线程都会持有一个threading.Event的对象,这些线程都会等待这个事件的“发生”,如果此事件一直不发生,那么这些线程将会阻塞,直至事件的“发生”。
对此,我们可以考虑一种应用场景(仅仅作为说明),例如,我们有多个线程从Redis队列中读取数据来处理,这些线程都要尝试去连接Redis的服务,一般情况下,如果Redis连接不成功,在各个线程的代码中,都会去尝试重新连接。如果我们想要在启动时确保Redis服务正常,才让那些工作线程去连接Redis服务器,那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作:主线程中会去尝试连接Redis服务,如果正常的话,触发事件,各工作线程会尝试连接Redis服务。
为此,我们可以写下如下的程序:
import threadingimport timeimport logginglogging.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]
threading.Event的wait方法还接受一个超时参数,默认情况下如果事件一致没有发生,wait方法会一直阻塞下去,而加入这个超时参数之后,如果阻塞时间超过这个参数设定的值之后,wait方法会返回。对应于上面的应用场景,如果Redis服务器一致没有启动,我们希望子线程能够打印一些日志来不断地提醒我们当前没有一个可以连接的Redis服务,我们就可以通过设置这个超时参数来达成这样的目的:
import threadingimport timeimport logginglogging.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线程之threading.Event
- Python 线程的使用(threading模块)
- Python:使用threading模块实现多线程编程八[使用Event实现线程间通信]
- Python:使用threading模块实现多线程编程八[使用Event实现线程间通信]
- 关于Python的进程线程协程之threading模块(三)Event对象
- python的threading模块中threading.RLock和threading.Lock
- python中threading的高级函数应用解析 Lock Rlock Condition Semaphore Timer Event Semaphore对象
- python中的线程使用--threading模块
- Python 使用threading 模块创建线程
- Python多线程编程,线程之间的协调
- Python中threading的问题
- python 中threading的运用
- python threading模块的使用
- Python多线程之threading Event
- python threading/Event & Timer(3)
- Python线程池(threading)
- python中使用threading进行多线程编程
- malloc函数详解
- mysql_ping()以及MYSQL_OPT_RECONNECT MySQL server has gone away”错误
- 微信分享总结
- UNIX的段错误和总线错误和Windows的保护性异常
- 微信开发-获取access_token
- Python中使用threading.Event协调线程的运行
- Hive-数据倾斜总结
- 打破商业孤岛 腾讯云德勤共建博思(BaaS)平台
- 很坚决去瞧瞧周傲天回家
- 百会云办公:国内首家微信办公一站式解决方案
- 总结java应用服务器 (2014年11月)
- List对象排序通用方法
- SIP:未来网络多媒体通信中的明星
- MySQL批量替换字符串