Python多執行緒Threading、子執行緒與守護執行緒例項詳解
本文例項講述了Python多執行緒Threading、子執行緒與守護執行緒。分享給大家供大家參考,具體如下:
執行緒與程序:
- 執行緒對於程序來說,就好似工廠裡的工人,分配資源是分配到工廠,工人再去處理。
- 執行緒是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。
- 在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒
- 對於IO密集型的程式來說,多執行緒可以利用讀IO的時間去做其他事【IO並不佔用CPU,這就好像A買個一份外賣,他只需要等著送過來然後敲A家的門就行了】;
- 而對於CPU密集型的程式來說,多執行緒的效率就不是很高了【CPU由於要計算,切換之間要恢復之前的現場消耗相對較大,比如我同時做幾份作業,一份作業做十分鐘,假如十分鐘做不完一份作業,那麼我後面再回頭做的時候,我就要好好想想剛才做到哪,剛才想到哪
補充:IO需要CPU嗎?知乎:https://www.zhihu.com/question/27734728
-
執行緒Threading:
python中多執行緒需要使用threading模組
執行緒的建立與執行:
1.直接呼叫threading的Thread類:
執行緒的建立:執行緒物件=thread.Thread(target=函式名,args=(引數))【補充,由於args是一個元組,單個引數時要加“,”】
執行緒的啟動:執行緒物件.start(),呼叫start(),那麼執行緒物件會自動去呼叫thread.Thread中的run()
讓主執行緒等待其餘執行緒結束:執行緒物件.join(),加了join之後,相當於阻塞了主執行緒,主執行緒只有當join的執行緒結束後才會向下執行
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多,說明是並行的結果
附加說明--join是阻塞等待:
import threading,time class MyTread(threading.Thread): def __init__(self,name): super(MyTread,self).__init__()#呼叫父類的__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)###主執行緒等待其餘執行緒結束 print(time.time()-start_time) #結果是2.0多,證明是join是相當於阻塞了主執行緒的執行,只有當執行緒結束後才會向下執行
2.繼承threading的Thread類:
繼承threading的Thread類的類要主要做兩件事:
1.如果不做自定義變數的初始化,那麼可以直接使用繼承的父類的__init__(),如果需要做自定義變數的初始化,則需要先呼叫父類的__init__()【否則需要自己填寫執行緒初始化相關的引數】
2.重寫run,雖然繼承了父類的run,但實際上如果不重寫,那麼我們繼承threading的Thread類又有什麼意義呢?為什麼不直接呼叫threading的Thread類
-
import threading,threading.active_count()) t1=MyTread("t1") t2=MyTread("t2") start_time=time.time() t1.start() t2.start() ###主執行緒等待其餘執行緒結束 t1.join() t2.join() print(time.time()-start_time)#結果是1.0多,證明是並行的
子執行緒:
- 由一個執行緒啟動的執行緒可以成為它的子執行緒,A啟動B,B是A的子執行緒,A是B的父執行緒
執行緒的幾個常用函式:
- threading.current_thread():
返回當前正在執行的執行緒物件
- threading.active_count():
返回當前程序中的存活的執行緒物件數
- 執行緒物件.isAlive()方法判斷執行緒是否存活
- getName(): 返回執行緒名。
- setName(): 設定執行緒名。
-
get_ident():獲取當前執行緒ID。
守護執行緒:
- 守護執行緒是起到輔助功能的,就好像魔法師放禁咒總要騎士保護一樣【魔法師只需要關係自己的任務,保護他的任務交給守護者】
- 而守護執行緒與主執行緒的關係呢,就好像備胎跟女神,去買東西的話,備胎要一直在外面等女神【守護執行緒執行結束就狗帶,但不影響主程序結束,由主執行緒決定執行時間】,女神不需要等待備胎【主執行緒結束,守護執行緒也要結束,不管自身任務是否完成】
- 與join的區別:join是阻塞等待,守護執行緒是並行的等待
- 設定守護執行緒:執行緒物件.setDaemon(True)【注意!!!!!設定守護執行緒必須要在start()前面,不然會報錯】
下面的程式碼顯示了主執行緒並不會等待其守護執行緒結束:
import threading,time class MyTread(threading.Thread): def __init__(self,self).__init__() self.name=name def run(self): print("守護執行緒已經啟動",self.name) time.sleep(1) print("run in task",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多,而且三個執行緒都執行完畢了,說明這個是並行的等待
讓主執行緒sleep一下,顯示一下如果主執行緒要等待守護執行緒,那麼是並行的等待:
import threading,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多,而且三個執行緒都執行完畢了,說明這個是並行的等待
更多關於Python相關內容感興趣的讀者可檢視本站專題:《Python程序與執行緒操作技巧總結》、《Python資料結構與演算法教程》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》、《Python入門與進階經典教程》、《Python+MySQL資料庫程式設計入門教程》及《Python常見資料庫操作技巧彙總》
希望本文所述對大家Python程式設計有所幫助。