1. 程式人生 > 程式設計 >Python多執行緒Threading、子執行緒與守護執行緒例項詳解

Python多執行緒Threading、子執行緒與守護執行緒例項詳解

本文例項講述了Python多執行緒Threading、子執行緒與守護執行緒。分享給大家供大家參考,具體如下:

執行緒與程序:

  • 執行緒對於程序來說,就好似工廠裡的工人,分配資源是分配到工廠,工人再去處理。
  • 執行緒是被系統獨立排程和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在執行中必不可少的資源,但它可與同屬一個程序的其它執行緒共享程序所擁有的全部資源。
  • 在單個程式中同時執行多個執行緒完成不同的工作,稱為多執行緒
  • 對於IO密集型的程式來說,多執行緒可以利用讀IO的時間去做其他事【IO並不佔用CPU,這就好像A買個一份外賣,他只需要等著送過來然後敲A家的門就行了】;
  • 而對於CPU密集型的程式來說,多執行緒的效率就不是很高了【CPU由於要計算,切換之間要恢復之前的現場消耗相對較大,比如我同時做幾份作業,一份作業做十分鐘,假如十分鐘做不完一份作業,那麼我後面再回頭做的時候,我就要好好想想剛才做到哪,剛才想到哪

    補充:IO需要CPU嗎?知乎:https://www.zhihu.com/question/27734728

    image


  • 執行緒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():
    返回當前正在執行的執行緒物件
    image
    • threading.active_count():
    返回當前程序中的存活的執行緒物件數

    image

    • 執行緒物件.isAlive()方法判斷執行緒是否存活

    image

    • getName(): 返回執行緒名。
    • setName(): 設定執行緒名。

    image

  • 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多,而且三個執行緒都執行完畢了,說明這個是並行的等待

    image

    讓主執行緒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多,而且三個執行緒都執行完畢了,說明這個是並行的等待

    image

更多關於Python相關內容感興趣的讀者可檢視本站專題:《Python程序與執行緒操作技巧總結》、《Python資料結構與演算法教程》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》、《Python入門與進階經典教程》、《Python+MySQL資料庫程式設計入門教程》及《Python常見資料庫操作技巧彙總》

希望本文所述對大家Python程式設計有所幫助。