Python中使用threading.Event協(xié)調(diào)線程的運(yùn)行詳解
threading.Event機(jī)制類似于一個線程向其它多個線程發(fā)號施令的模式,其它線程都會持有一個threading.Event的對象,這些線程都會等待這個事件的“發(fā)生”,如果此事件一直不發(fā)生,那么這些線程將會阻塞,直至事件的“發(fā)生”。
對此,我們可以考慮一種應(yīng)用場景(僅僅作為說明),例如,我們有多個線程從Redis隊列中讀取數(shù)據(jù)來處理,這些線程都要嘗試去連接Redis的服務(wù),一般情況下,如果Redis連接不成功,在各個線程的代碼中,都會去嘗試重新連接。
如果我們想要在啟動時確保Redis服務(wù)正常,才讓那些工作線程去連接Redis服務(wù)器,那么我們就可以采用threading.Event機(jī)制來協(xié)調(diào)各個工作線程的連接操作:
主線程中會去嘗試連接Redis服務(wù),如果正常的話,觸發(fā)事件,各工作線程會嘗試連接Redis服務(wù)。
為此,我們可以寫下如下的程序:
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()
運(yùn)行這個程序:
(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服務(wù)器啟動的地方,一旦主線程確定了redis服務(wù)器已經(jīng)正常啟動,那么會觸發(fā)redis_ready事件,各個工作線程就會去連接redis去做相應(yīng)的工作。
threading.Event的wait方法還接受一個超時參數(shù),默認(rèn)情況下如果事件一直沒有發(fā)生,wait方法會一直阻塞下去,而加入這個超時參數(shù)之后,如果阻塞時間超過這個參數(shù)設(shè)定的值之后,wait方法會返回。
對應(yīng)于上面的應(yīng)用場景,如果Redis服務(wù)器一致沒有啟動,我們希望子線程能夠打印一些日志來不斷地提醒我們當(dāng)前沒有一個可以連接的Redis服務(wù),我們就可以通過設(shè)置這個超時參數(shù)來達(dá)成這樣的目的:
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循環(huán),直到redis_ready事件觸發(fā)之后才會結(jié)束循環(huán),wait方法調(diào)用會在1秒的超時后返回,這樣,我們就可以看到各個工作線程在系統(tǒng)啟動的時候等待redis_ready的同時,會記錄一些狀態(tài)信息。
以下是這個程序的運(yùn)行結(jié)果:
(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服務(wù)啟動的同時,看到工作線程里正在等待的情況。
以上這篇Python中使用threading.Event協(xié)調(diào)線程的運(yùn)行詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Python多線程同步Lock、RLock、Semaphore、Event實(shí)例
- 分析Python感知線程狀態(tài)的解決方案之Event與信號量
- python基于event實(shí)現(xiàn)線程間通信控制
- python Event事件、進(jìn)程池與線程池、協(xié)程解析
- 詳解Python 多線程 Timer定時器/延遲執(zhí)行、Event事件
- 詳解python多線程、鎖、event事件機(jī)制的簡單使用
- python多線程之事件Event的使用詳解
- Python多線程編程(八):使用Event實(shí)現(xiàn)線程間通信
- python中Event實(shí)現(xiàn)線程間同步介紹
相關(guān)文章
使用Python內(nèi)置模塊與函數(shù)進(jìn)行不同進(jìn)制的數(shù)的轉(zhuǎn)換
這篇文章主要介紹了使用Python內(nèi)置模塊與函數(shù)進(jìn)行不同進(jìn)制的數(shù)的轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
python學(xué)習(xí)VSCode使用技巧帶你進(jìn)入高效開發(fā)模式
VsCode是一款開源的編輯器,擁有強(qiáng)大的功能,。由于擁有各種各樣的插件,這就使得VsCode可以做到的事情更多了。在使用的過程中,也是有很多技巧的,掌握一些技巧對于后期寫代碼也會輕松很多2021-09-09
Python存儲json數(shù)據(jù)發(fā)生亂碼的解決方法
當(dāng)使用json.dump()把python對象轉(zhuǎn)換為json后存儲到文件中時,文件可能會出現(xiàn)亂碼的問題,本篇文章可以幫助您解決亂碼問題,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
Python爬取豆瓣數(shù)據(jù)實(shí)現(xiàn)過程解析
這篇文章主要介紹了Python爬取豆瓣數(shù)據(jù)實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
Python?range函數(shù)生成一系列連續(xù)整數(shù)的內(nèi)部機(jī)制解析
這篇文章主要為大家介紹了Python?range函數(shù)生成一系列連續(xù)整數(shù)的內(nèi)部機(jī)制解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12

