Python多線程Threading、子線程與守護線程實例詳解
本文實例講述了Python多線程Threading、子線程與守護線程。分享給大家供大家參考,具體如下:
線程與進程:
- 線程對于進程來說,就好似工廠里的工人,分配資源是分配到工廠,工人再去處理。
- 線程是被系統(tǒng)獨立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源。
- 在單個程序中同時運行多個線程完成不同的工作,稱為多線程
- 對于IO密集型的程序來說,多線程可以利用讀IO的時間去做其他事【IO并不占用CPU,這就好像A買個一份外賣,他只需要等著送過來然后敲A家的門就行了】;
- 而對于CPU密集型的程序來說,多線程的效率就不是很高了【CPU由于要計算,切換之間要恢復(fù)之前的現(xiàn)場消耗相對較大,比如我同時做幾份作業(yè),一份作業(yè)做十分鐘,假如十分鐘做不完一份作業(yè),那么我后面再回頭做的時候,我就要好好想想剛才做到哪,剛才想到哪】
補充:IO需要CPU嗎?知乎:https://www.zhihu.com/question/27734728

-
線程Threading:
python中多線程需要使用threading模塊
線程的創(chuàng)建與運行:
1.直接調(diào)用threading的Thread類:
線程的創(chuàng)建:線程對象=thread.Thread(target=函數(shù)名,args=(參數(shù)))【補充,由于args是一個元組,單個參數(shù)時要加“,”】
線程的啟動:線程對象.start(),調(diào)用start(),那么線程對象會自動去調(diào)用thread.Thread中的run()
讓主線程等待其余線程結(jié)束:線程對象.join(),加了join之后,相當(dāng)于阻塞了主線程,主線程只有當(dāng)join的線程結(jié)束后才會向下執(zhí)行
import threading,time def run(n): time.sleep(1) print("task ",n) t1=threading.Thread(target=run,args=("t1",)) t2 = threading.Thread(target=run,args=("t2",)) start_time=time.time()#開始時間 t1.start() t2.start() ##因為是獨立線程,如果想要主線程等待其他線程運行完畢,需要使用join t1.join() t2.join() spend_time=time.time()-start_time print(spend_time)##1.0多,說明是并行的結(jié)果附加說明--join是阻塞等待:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__()#調(diào)用父類的__init__() self.name=name def run(self):#重寫方法,按自己的要求去寫 time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1") t2=MyTread("t2") start_time=time.time() t1.start() t2.start() t1.join() t2.join() time.sleep(1)###主線程等待其余線程結(jié)束 print(time.time()-start_time) #結(jié)果是2.0多,證明是join是相當(dāng)于阻塞了主線程的執(zhí)行,只有當(dāng)線程結(jié)束后才會向下執(zhí)行2.繼承threading的Thread類:
繼承threading的Thread類的類要主要做兩件事:
1.如果不做自定義變量的初始化,那么可以直接使用繼承的父類的__init__(),如果需要做自定義變量的初始化,則需要先調(diào)用父類的__init__()【否則需要自己填寫線程初始化相關(guān)的參數(shù)】
2.重寫run,雖然繼承了父類的run,但實際上如果不重寫,那么我們繼承threading的Thread類又有什么意義呢?為什么不直接調(diào)用threading的Thread類
-
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__()#調(diào)用父類的__init__() self.name=name def run(self):#重寫方法,按自己的要求去寫 time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1") t2=MyTread("t2") start_time=time.time() t1.start() t2.start() ###主線程等待其余線程結(jié)束 t1.join() t2.join() print(time.time()-start_time)#結(jié)果是1.0多,證明是并行的
子線程:
- 由一個線程啟動的線程可以成為它的子線程,A啟動B,B是A的子線程,A是B的父線程
線程的幾個常用函數(shù):
- threading.current_thread():
返回當(dāng)前正在運行的線程對象

- threading.active_count():
返回當(dāng)前進程中的存活的線程對象數(shù)

- 線程對象.isAlive()方法判斷線程是否存活

- getName(): 返回線程名。
- setName(): 設(shè)置線程名。

-
get_ident():獲取當(dāng)前線程ID。
守護線程:
- 守護線程是起到輔助功能的,就好像魔法師放禁咒總要騎士保護一樣【魔法師只需要關(guān)系自己的任務(wù),保護他的任務(wù)交給守護者】
- 而守護線程與主線程的關(guān)系呢,就好像備胎跟女神,去買東西的話,備胎要一直在外面等女神【守護線程運行結(jié)束就狗帶,但不影響主進程結(jié)束,由主線程決定運行時間】,女神不需要等待備胎【主線程結(jié)束,守護線程也要結(jié)束,不管自身任務(wù)是否完成】
- 與join的區(qū)別:join是阻塞等待,守護線程是并行的等待
- 設(shè)置守護線程:線程對象.setDaemon(True)【注意?。。。。≡O(shè)置守護線程必須要在start()前面,不然會報錯】
下面的代碼顯示了主線程并不會等待其守護線程結(jié)束:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__() self.name=name def run(self): print("守護線程已經(jīng)啟動",self.name) time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1") t1.setDaemon(True) t2=MyTread("t2") t2.setDaemon(True) start_time=time.time()#開始時間 t1.start() t2.start() spend_time=time.time()-start_time print(spend_time)##0.0多,而且三個線程都執(zhí)行完畢了,說明這個是并行的等待
讓主線程sleep一下,顯示一下如果主線程要等待守護線程,那么是并行的等待:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__() self.name=name def run(self): print("守護線程已經(jīng)啟動",self.name) time.sleep(1) print("run in task",self.name,threading.current_thread(),threading.active_count()) t1=MyTread("t1") t1.setDaemon(True) t2=MyTread("t2") t2.setDaemon(True) start_time=time.time()#開始時間 t1.start() t2.start() time.sleep(2) spend_time=time.time()-start_time print(spend_time)##2.0多,而且三個線程都執(zhí)行完畢了,說明這個是并行的等待
更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python進程與線程操作技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進階經(jīng)典教程》、《Python+MySQL數(shù)據(jù)庫程序設(shè)計入門教程》及《Python常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家Python程序設(shè)計有所幫助。
相關(guān)文章
python淘寶準(zhǔn)點秒殺搶單的實現(xiàn)示例
為了想要搶到想要的商品,想了個用Python實現(xiàn)python淘寶準(zhǔn)點秒殺搶單方案,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
將tf.batch_matmul替換成tf.matmul的實現(xiàn)
這篇文章主要介紹了將tf.batch_matmul替換成tf.matmul的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
python Xarray處理設(shè)置二維數(shù)組作為coordinates方式
這篇文章主要介紹了python Xarray處理設(shè)置二維數(shù)組作為coordinates方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
對python以16進制打印字節(jié)數(shù)組的方法詳解
今天小編就為大家分享一篇對python以16進制打印字節(jié)數(shù)組的方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01
詳解解決Python memory error的問題(四種解決方案)
這篇文章主要介紹了詳解解決Python memory error的問題(四種解決方案),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Python利用pdfplumber實現(xiàn)讀取PDF寫入Excel
pdfplumber專注PDF內(nèi)容提取,例如文本(位置、字體及顏色等)和形狀(矩形、直線、曲線),還有解析表格的功能。本文主要為大家介紹如何利用pdfplumber實現(xiàn)讀取PDF寫入Excel,需要的可以參考一下2022-06-06

