python中的threading_python中的threading模块使用说明
這段時(shí)間使用python做串口的底層庫(kù),用到了多線程,對(duì)這部分做一下總結(jié)。實(shí)際用完了后再回過頭去看python的官方幫助文檔,感覺受益匪淺,把里面的自己覺得有用的一些關(guān)鍵點(diǎn)翻譯出來,留待后續(xù)查驗(yàn)。
threading是thread的高級(jí)接口模塊,包括了除了thread模塊,還有mutex模塊、queue模塊、dummy_threading模塊方面的內(nèi)容。
該模塊定義了一下幾方面的函數(shù)和對(duì)象:
threading.activeCount() :返回現(xiàn)存在活動(dòng)狀態(tài)的線程數(shù)。返回的數(shù)目等于enumerate()列表的長(zhǎng)度。
threading.Condition():是返回一個(gè)新的condition變量類型的工廠函數(shù)(返回對(duì)象的函數(shù))。一個(gè)condition類型的變量允許一個(gè)或多個(gè)線程等待,直到被另一個(gè)線程通知。
threading.currentThread() :根據(jù)用戶線程句柄,返回當(dāng)前的線程對(duì)象。如果線程句柄并未通過threading模塊創(chuàng)建,有限功能的啞線程會(huì)被創(chuàng)建。
threading.enumerate() :返回所有活動(dòng)線程對(duì)象列表。包括守護(hù)線程、由current_thread()創(chuàng)建的啞線程以及主線程。不包括終止了的線程和未開始的線程。
threading.Event() :是返回一個(gè)新的event類型的工廠函數(shù)。一個(gè)event管理一個(gè)標(biāo)識(shí),可以使用set()方法設(shè)置為true,也可以由clear()方法重置為false。wait()方法會(huì)阻塞直到這個(gè)標(biāo)識(shí)為true。
class threading.local:代表線程本地?cái)?shù)據(jù)的類。線程本地?cái)?shù)據(jù)是該線程獨(dú)有的。通過創(chuàng)建一個(gè)local實(shí)例,可以管理線程本地?cái)?shù)據(jù),并且能存儲(chǔ)其屬性。如:
mydata = threading.local()
mydata.x = 1
該屬性的值因線程不同而異。
threading.Lock() :是一個(gè)返回新的單鎖對(duì)象的工廠函數(shù)。只要一個(gè)線程獲取該鎖,相關(guān)其他要獲取該鎖的線程都會(huì)阻塞,直到鎖被釋放。任何線程都可以釋放它。
eg:
testLock=threading.Lock()
testLock.acquire()#對(duì)鎖的使用,也可以不用acquire()和release,直接使用with testLock:即可
self._test=True
testLock.release()
(注意:互斥鎖用來鎖定不同線程中的互斥量,鎖的內(nèi)容盡可能簡(jiǎn)潔,只鎖定必須互斥的部分,以節(jié)省線程運(yùn)轉(zhuǎn)的時(shí)間)
threading.RLock() :返回一個(gè)可重入鎖的工廠函數(shù)。可重入鎖必須由創(chuàng)建它的線程釋放。一旦一個(gè)線程獲取了一個(gè)可重入鎖,同一線程內(nèi)可以繼續(xù)獲取它而不阻塞。線程獲取了幾次可重入鎖,必須釋放同樣的次數(shù)。
(在此次項(xiàng)目實(shí)踐中,重鎖沒有用到,但知道了這樣的場(chǎng)景,即同一線程,如果鎖中間調(diào)用的函數(shù),有用到同樣的鎖,如果用單鎖,會(huì)發(fā)生死鎖,而用可重入鎖,不會(huì)發(fā)生阻塞,可以防止這樣場(chǎng)景下的死鎖。)
threading.Semaphore([value]) :是返回一個(gè)新的信號(hào)量對(duì)象的工廠函數(shù)。信號(hào)量管理一個(gè)計(jì)數(shù)器,代表調(diào)用release()的個(gè)數(shù)減去調(diào)用acquire(),再加上初始值的數(shù)目。當(dāng)該值為負(fù)數(shù)時(shí),acquire()方法會(huì)阻塞。value的默認(rèn)值是1。
(當(dāng)時(shí)考系統(tǒng)分析師,對(duì)于信號(hào)量總是理解的很抽象,其實(shí)就是控制線程同步和互斥量的。當(dāng)初創(chuàng)建這一概念的科學(xué)家使用p()和V()取代了acquire()和release()。信號(hào)量管理一個(gè)內(nèi)部計(jì)數(shù)器,每調(diào)用一個(gè)acquire()就遞減一次,每調(diào)用release()就遞增一次。這個(gè)計(jì)數(shù)器不能小于0。一旦調(diào)用acquire()時(shí)發(fā)現(xiàn)它小于0,則線程阻塞,直到其他線程調(diào)用release()。)
class threading.Thread:代表線程句柄的類。
threading用于提供線程相關(guān)的操作,線程是應(yīng)用程序中工作的最小單元。python當(dāng)前版本的多線程庫(kù)沒有實(shí)現(xiàn)優(yōu)先級(jí)、線程組,線程也不能被停止、暫停、恢復(fù)、中斷。
thread是線程類,有兩種使用方法,直接傳入要運(yùn)行的方法(推薦,簡(jiǎn)便)或從thread繼承并覆蓋run()。一旦線程對(duì)象被創(chuàng)建,必須調(diào)用線程的start()方法開始線程。這一操作會(huì)喚醒每個(gè)線程的run()方法。當(dāng)線程開始后,這個(gè)線程被認(rèn)為是活動(dòng)的。當(dāng)它的run()方法終結(jié),線程就結(jié)束了,或者通常的做法是,是觸發(fā)一個(gè)不能處理的異常。可以用is_alive()方法判斷線程是否活動(dòng)。
其他線程可以調(diào)用某個(gè)線程的join()方法。這會(huì)阻塞當(dāng)前上下文環(huán)境的線程,直到調(diào)用此方法的線程終止。
一個(gè)線程可以被標(biāo)識(shí)為“守護(hù)線程”。當(dāng)所有子線程為守護(hù)線程時(shí),如果主線程結(jié)束,則所有子線程也就結(jié)束了。比較優(yōu)雅的退出方法是引入event拋出異常。
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
group:必須是none,留待后續(xù)擴(kuò)展應(yīng)用。
target:被調(diào)用的函數(shù)對(duì)象
name:線程名,可默認(rèn)不填,由系統(tǒng)自動(dòng)創(chuàng)建
args:調(diào)用函數(shù)對(duì)象的傳參,是一個(gè)元祖類型
kwargs:函數(shù)傳參,是字典類型
如果子類重載了此構(gòu)造函數(shù),必須在對(duì)此線程操作之前,在子類中顯式調(diào)用構(gòu)造函數(shù)(thread.__init__())
start():每個(gè)線程中只能最多調(diào)用一次,否則會(huì)拋出運(yùn)行錯(cuò)誤。
run():在子類中重載此方法。
join([timeout]):等待直到線程終結(jié)。這會(huì)阻塞當(dāng)前上下文環(huán)境的線程,直到調(diào)用此方法的線程終止或超時(shí)。
(因此當(dāng)所有子線程結(jié)束后,主線程才會(huì)結(jié)束)
isAlive():返回該線程是否活動(dòng)。
daemon:setDaemon()必須在線程啟動(dòng)start()之前調(diào)用,否則會(huì)拋出運(yùn)行錯(cuò)誤異常。
condition對(duì)象:一個(gè)condition對(duì)象通常和某種鎖關(guān)聯(lián)。condition變量擁有acquire()和release()方法,可調(diào)用相應(yīng)的鎖。還有wait()方法,notify()方法和notifyall()方法,但這三種方法必須在獲取到鎖之后進(jìn)行,否則會(huì)拋出運(yùn)行錯(cuò)誤異常。
class threading.Condition([lock]) :如果參數(shù)lock給出,必須是Lock或RLock的對(duì)象。
acquire(*args):獲取一個(gè)基礎(chǔ)鎖。
release() :釋放鎖
wait([timeout]) :等待,直到被通知或者超時(shí)。如果線程沒有獲取到鎖,而調(diào)用了這個(gè)方法,則會(huì)拋出運(yùn)行錯(cuò)誤異常。
此消息會(huì)釋放基礎(chǔ)鎖,然后阻塞直到因?yàn)樵诹硪痪€程的同樣的condition變量被notify或notifyAll()喚醒,一旦喚醒或超時(shí),會(huì)重新獲取鎖并返回(好拗口,直白的意思就是“我累了,休息會(huì)兒,資源你們先拿去用”,然后要等待其他獲取鎖的線程,調(diào)用條件變量的notify或者nofityAll方法,才能把原有等待的線程喚醒繼續(xù)執(zhí)行)。
如果鎖是一個(gè)可重入鎖,并不能通過release方法被釋放,原因是當(dāng)它被鎖了好多次的時(shí)候,這可能并沒有真的解開鎖。然而,一個(gè)可重入鎖磊的內(nèi)部接口被使用,這可以真的解開鎖即便鎖被獲取了多次。
notify(n=1):默認(rèn)情況下,喚醒一個(gè)等待的情況變量。
Event對(duì)象:這是最簡(jiǎn)單的線程間通信機(jī)制之一:一個(gè)線程釋放一個(gè)event事件,而其他線程捕捉它。
一個(gè)event對(duì)象管理一個(gè)內(nèi)部標(biāo)識(shí)可以通過set()方法設(shè)為true,也可以通過clear()方法設(shè)為false。wait()方法會(huì)阻塞,直到該標(biāo)識(shí)為True。默認(rèn)是False
set():設(shè)置該標(biāo)識(shí)為True。所有等待它為True的線程會(huì)被喚醒。調(diào)用wait()的線程,一旦該標(biāo)識(shí)為True就不會(huì)再阻塞。
clear():設(shè)置該標(biāo)識(shí)為false。相應(yīng)地,調(diào)用wait的線程會(huì)阻塞,直到調(diào)用set方法把標(biāo)識(shí)設(shè)為true
wait():當(dāng)內(nèi)部標(biāo)識(shí)為true時(shí)阻塞。如果該內(nèi)部標(biāo)識(shí)一開始就是true,直接返回。否則,會(huì)阻塞知道其他線程調(diào)用se()把標(biāo)識(shí)設(shè)為true,或者直到可選的超時(shí)發(fā)生。
總結(jié)
以上是生活随笔為你收集整理的python中的threading_python中的threading模块使用说明的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react项目打包
- 下一篇: 二、scrapy爬虫框架——scrapy