百度T7架構(gòu)師對(duì)于Python中多線程總結(jié)

多線程

一個(gè)進(jìn)程中有多個(gè)線程就是多線程。

一個(gè)進(jìn)程中至少有一個(gè)線程,并作為程序的入口,這個(gè)就是主線程。一個(gè)進(jìn)程至少有一個(gè)主進(jìn)程,其他線程稱為工作線程。

線程安全:線程執(zhí)行一段代碼,不會(huì)產(chǎn)生不確定的結(jié)果,那這段代碼就是線程安全。(例如print()線程不安全)

線程的daemon屬性

daemon屬性:表示線程是否是daemon線程,這個(gè)值必須在start()之前設(shè)置,否則引發(fā)RuntimeError異常

isDaemon():是否是daemon線程

setDaemon():設(shè)置為daemon線程,必須在start方法之前設(shè)置

線程具有一個(gè)daemon屬性,可以設(shè)置為Ture或False,也可以不設(shè)置,默認(rèn)值為None.如果不設(shè)置daemon就取當(dāng)前的daemon來(lái)設(shè)置它,主線程是Non-daemon。工作線程不設(shè)置daemon屬性,則默認(rèn)是daemon = False .python程序在沒(méi)有活著的non-daemon線程運(yùn)行時(shí)退出。

join()方法

join(timeout)是線程的標(biāo)準(zhǔn)方法之一。

一個(gè)線程中調(diào)用里那個(gè)一個(gè)線程的join方法,調(diào)用者將被阻塞,知道盜用線程終止。一個(gè)線程可以被join多次。

daemon線程的應(yīng)用場(chǎng)景

1:后臺(tái)任務(wù),如發(fā)送心跳包、監(jiān)控,這種場(chǎng)景最多

2:主線程工作才有用的線程,如主線程中維護(hù)的公共資源,主線程已經(jīng)清理了,準(zhǔn)備退出,而工作線程使用這些資源工作也沒(méi)有意義了,一起退出最合適。

3:隨時(shí)可以被終止的線程

threading.local類

運(yùn)行時(shí),threading.local實(shí)例處在不同的線程中,就從大字典中找到當(dāng)前線程相關(guān)鍵值對(duì)中的字典,覆蓋threading.local實(shí)例的__dict__。這樣就可以在不同的線程中,安全德使用線程獨(dú)有的數(shù)據(jù)做到線程間數(shù)據(jù)隔離,如同本地變量一樣安全。

定時(shí)器Timer/延遲執(zhí)行

threading.Timer(interval,function,args=None,Kwargs=None)

start方法執(zhí)行之后,Timer對(duì)象會(huì)處于等待狀態(tài),等待了interval秒之后,開(kāi)始執(zhí)行function函數(shù)的。Timer提供了cancel方法,用來(lái)取消一個(gè)未執(zhí)行的函數(shù)。

Event

是線程間通信機(jī)制中最簡(jiǎn)單的實(shí)現(xiàn),使用一個(gè)內(nèi)部的標(biāo)記flag,通過(guò)flag的True或False的表?yè)Q來(lái)進(jìn)行操作。

set():標(biāo)記設(shè)置為Ture

clear():標(biāo)記設(shè)置為False

is_set():標(biāo)記是否為Ture

wait(timeou):設(shè)置等待標(biāo)記為Ture的時(shí)長(zhǎng),None為無(wú)限等待,等到返回Ture,未等到超時(shí)了返回False

Event的wait優(yōu)于time.sleep,他會(huì)更快的切換到其它線程,提高并發(fā)效率。

lock

鎖,凡是存在共享資源爭(zhēng)搶的地方都可以使用鎖,從而保證只有一個(gè)使用者可以完全使用這個(gè)資源。一旦線程獲得鎖,其他試圖獲取鎖的線程將被阻塞。

acquire(blocking=True,timeout=-1):默認(rèn)阻塞,阻塞可以設(shè)置超時(shí)時(shí)間,非阻塞時(shí),timeout禁止設(shè)置。成功獲取鎖,返回True,否則返回Flase

release():釋放鎖,可以從任何線程調(diào)用釋放。已上鎖的多,會(huì)被重置未unlocked。未上鎖的調(diào)用,會(huì)派出RuntimeError異常。

加鎖、解鎖

一般來(lái)說(shuō),加鎖就需要解鎖,但加鎖后解鎖前,還有一些代碼執(zhí)行,就有可能拋出異常,一旦出現(xiàn)異常,鎖無(wú)法釋放,但是當(dāng)前線程可能因?yàn)檫@個(gè)異常被終止了,這就產(chǎn)生了死鎖。

加鎖、解鎖常用的語(yǔ)句:

1:使用try ... funally語(yǔ)句保證鎖的釋放

2:with上下文管理,鎖隨想支持上下位管理。

鎖的應(yīng)用:

鎖適合用于訪問(wèn)和修改同一個(gè)共享資源的時(shí)候,即讀寫同一個(gè)資源的時(shí)候。

注意事項(xiàng):

1:少用鎖,必要時(shí)使用鎖,使用了鎖,多線程訪問(wèn)被鎖的資源時(shí),就成了串行,要么排隊(duì)執(zhí)行,要么爭(zhēng)搶執(zhí)行。

2:加鎖時(shí)間越短越好,不需要就立即釋放。

3:一定要避免死鎖。

Rlock可重入鎖

可重入鎖,是線程相關(guān)的鎖??稍谝粋€(gè)線程中獲取鎖,并可繼續(xù)在同一個(gè)線程中不阻塞獲取鎖,當(dāng)鎖為釋放完,其他線程獲取鎖就會(huì)阻塞。知道當(dāng)前持有鎖的線程釋放完鎖。

Conditon

構(gòu)造方法Consition(lock=None),可以傳入一個(gè)Lock或者Rlock對(duì)象,默認(rèn)是Rlock

acquire(*args):獲取鎖

wait(self.timeout=None):等待或超時(shí)

notify(n =1):?jiǎn)拘阎炼嘀付〝?shù)目個(gè)數(shù)的等待的線程,沒(méi)有線程等待的線程就沒(méi)有任何操作

notify_all():?jiǎn)拘阉械却木€程

condition用于生產(chǎn)者,消費(fèi)者模型,為了解決生產(chǎn)者消費(fèi)者速度匹配的問(wèn)題。由于condition內(nèi)部使用了鎖,最好的方式是使用with上下文。

Barrier

Barrier(parties,action=None,timeout=None):構(gòu)建Barrier對(duì)象,指定參與方數(shù)目。timeout是wait方法未指定超時(shí)的默認(rèn)值。

n_waiting:當(dāng)前在barrier中等待的線程數(shù)

parties:資源的個(gè)數(shù)。

broken:如果broken處于打破的狀態(tài),放回True

abort():將將barrier置于broken狀態(tài),等待中的線程或者調(diào)用等待方法的線程中都會(huì)拋出BrokenBarrierError異常,知道reset方法來(lái)恢復(fù)barrier

reset():恢復(fù)barrier,重新開(kāi)始攔截。

wait方法超時(shí)發(fā)生,barrier將處于broken狀態(tài),知道reset()

semaphore信號(hào)量

Semaphore(value=1):構(gòu)造方法,value小于0,拋ValueError異常

acquite(blocking=True,timeout=None):獲取信號(hào)量,計(jì)數(shù)器減1,獲取成功返回True

release():釋放信號(hào)量,計(jì)數(shù)器加1

semaphore問(wèn)題

如果遇到release釋放次數(shù)大于初始值,計(jì)數(shù)器會(huì)增加,超過(guò)我們的最大值。

解決方法:

使用Boundedsemaphore類,有界信號(hào)量,不允許使用release超出初始值的范圍,否則派出ValueError異常。

鎖和信號(hào)量

鎖,只允許同一個(gè)時(shí)間一個(gè)線程獨(dú)占資源,它是特殊的信號(hào)量,即信號(hào)量計(jì)數(shù)器初始值為1.

信號(hào)量,可以多個(gè)線程訪問(wèn)共享資源,但這個(gè)共享資源數(shù)量有限。

鎖,可以看做特殊的型號(hào)量。

如果需要Python方面的入門知識(shí)可以點(diǎn)擊這個(gè)鏈接獲取入門資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【threading模塊詳解】 模塊基本方法 該模塊定了的方法如下:threading.active_count(...
    奕劍聽(tīng)雨閱讀 1,154評(píng)論 0 0
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記,整理的知識(shí)點(diǎn),也是為了防止忘記,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦!如果你也喜歡,那...
    波波波先森閱讀 11,644評(píng)論 4 56
  • 一. 操作系統(tǒng)概念 操作系統(tǒng)位于底層硬件與應(yīng)用軟件之間的一層.工作方式: 向下管理硬件,向上提供接口.操作系統(tǒng)進(jìn)行...
    月亮是我踢彎得閱讀 6,179評(píng)論 3 28
  • 線程 操作系統(tǒng)線程理論 線程概念的引入背景 進(jìn)程 之前我們已經(jīng)了解了操作系統(tǒng)中進(jìn)程的概念,程序并不能單獨(dú)運(yùn)行,只有...
    go以恒閱讀 1,800評(píng)論 0 6
  • 引子:作者維克多?弗朗克爾在經(jīng)歷了納粹集中營(yíng)后發(fā)現(xiàn),能存活的人都是有著堅(jiān)定信念(為了至愛(ài)、余生要完成某種重要事情等...
    十萬(wàn)千瓦閱讀 728評(píng)論 4 2

友情鏈接更多精彩內(nèi)容