国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

python并發(fā)入門(part5 event對象)

2021-08-31 11:00 作者:Vecloud_  | 我要投稿


一、引入event。?
每個線程,都是一個獨立運行的個體,并且每個線程的運行狀態(tài)是無法預測的。?

如果一個程序中有很多個線程,程序的其他線程需要判斷某個線程的運行狀態(tài),來確定自己下一步要執(zhí)行哪些操作。?
threading模塊中的event對象恰好能做到這一點,event對象包含了一個可以通過線程設(shè)置的一個信號標志位,它允許線程一直等待某些事件的發(fā)生。?
在初始化默認的情況下,event對象中的信號標識被設(shè)置為“假”,如果這時,有一個線程等待這個event對象,而這個event對象的信號標志為“假”,那么這個線程就會被一直阻塞下去,直到這個event信號標志為“真”,所有等待這個event對象的線程才會被喚醒。?

也就是說,一個線程如果等待的event對象中的信號標志位“真”,這個線程會忽略這個事件(event),繼續(xù)執(zhí)行。?


二、event對象的常用方法。?
event.isSet():返回event的狀態(tài)值。?
event.wait():?當event對象內(nèi)部的信號標識設(shè)置為“假”(False),所有等待這個event對象的線程將會全部被阻塞。?


event.set():設(shè)置event對象內(nèi)部的信號標識為“真”(True),所有等待這個event對象的線程將會被喚醒,等待操作系統(tǒng)的調(diào)度。?


event.clear():恢復event的狀態(tài)值為False。?

三、event使用示例。?
我們來考慮下event對象的應(yīng)用場景。?

假如,在一個程序中,有多個線程需要到redis中來取數(shù)據(jù),每個線程都要去嘗試著去連接redis服務(wù)器,一般情況下,redis如果連接不成功,在所有線程中都需要嘗試著去重新連接。?
如果我們想要在程序啟動時,先要確保redis服務(wù)器工作正常,接著在讓其他工作的線程去連接redis服務(wù)器,當遇到這種需求的時候,使用event對象就是一個非常不錯的選擇。?
我們可以使用event機制去讓各個工作的線程去做一個簡單的通信,主線程去連接redis服務(wù)器,如果連接到了,event對象內(nèi)的信號標識改為真,其余工作的線程就會被喚醒。?


示例:?
#!/usr/local/bin/python2.7?
# -*- coding:utf-8 -*-?
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)?
def main():?
??redis_ready = threading.Event()?
??t1 = threading.Thread(target=worker,args=(redis_ready,),name="threading-1")?
??t1.start()?
??t2 = threading.Thread(target=worker,args=(redis_ready,),name="threading-2")?
??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)?
??redis_ready.set()?
if __name__ == '__main__':?
??main()?


輸出結(jié)果:?
(threading-1) waiting for redis ready....?
(threading-2) waiting for redis ready....?
(MainThread) first of all,check redis server, make sure it is ok , and then trigger the redis ready event?
(threading-1) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017?
(threading-2) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017?


代碼分析:?
在上面這段代碼中,一共開了三個線程,分別是threading-1和threading-2還有主線程,首先主線程運行了main()函數(shù),產(chǎn)生了一個event對象,這個event對象信號的初始值是False,然后創(chuàng)建了threading-1和threading-2兩個線程并且運行,輸出一條日志first of all,check redis server, make sure it is ok , and then trigger the redis ready event后sleep 3秒,此時切換到了threading-1,threading-1首先執(zhí)行了worker函數(shù),輸出一次日志,然后執(zhí)行event.wait方法,當這個event對象的信號標識為False時,threading-1就被阻塞住了,暫時無法執(zhí)行woker函數(shù)后面的內(nèi)容,當threading-1被阻塞住后,隨即切換到threading-2(為什么一定切換到threading-2呢?這是因為主線程還在sleep),threading-2此時也去執(zhí)行woker函數(shù),同樣先輸出一條日志waiting for redis ready....,當執(zhí)行到event.wait時,這個event對象的信號標志位依舊為False,所以執(zhí)行到這里的時候,threading-2也會被阻塞。?
過了3秒后,MainThread主線程sleep結(jié)束,開始向下運行,執(zhí)行了redis_ready.set()后,我們創(chuàng)建的那個名為redis_ready的event對象中的信號標志會變?yōu)門rue,當這event對象的信號標志變?yōu)門rue之后,之前阻塞的threading-1和threading-2都會被喚醒,繼續(xù)執(zhí)行woker函數(shù)后面的代碼。?
(threading-1) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017?
(threading-2) redis ready,and connect to redis server and do some work Sun May 14 09:35:46 2017?

四、event對象的補充。?
threading.Event的wait方法還接受一個超時參數(shù),默認情況下如果事件一致沒有發(fā)生,wait方法會一直阻塞下去,而加入這個超時參數(shù)之后,如果阻塞時間超過這個參數(shù)設(shè)定的值之后,wait方法會返回。對應(yīng)于上面的應(yīng)用場景,如果Redis服務(wù)器一致沒有啟動,我們希望子線程能夠打印一些日志來不斷地提醒我們當前沒有一個可以連接的Redis服務(wù),我們就可以通過設(shè)置這個超時參數(shù)來達成這樣的目的:

了解更多網(wǎng)絡(luò)知識關(guān)注:http://www.vecloud.com/

python并發(fā)入門(part5 event對象)的評論 (共 條)

分享到微博請遵守國家法律
深水埗区| 五指山市| 澎湖县| 鸡东县| 韩城市| 镇宁| 惠州市| 广昌县| 方正县| 博湖县| 边坝县| 通化县| 安达市| 开阳县| 凌源市| 嘉义市| 诸城市| 陇西县| 神农架林区| 临沂市| 虹口区| 芒康县| 凉城县| 棋牌| 华亭县| 远安县| 龙山县| 娱乐| 兰溪市| 宿松县| 嵊泗县| 湘阴县| 湘乡市| 德昌县| 吉安市| 乐清市| 凤冈县| 玉林市| 双辽市| 茶陵县| 乐安县|