Python中threading的join和setDaemon的區別及用法[例子]

Candy_GL發表於2018-10-08

Python多執行緒程式設計時,經常會用到join()和setDaemon()方法,今天特地研究了一下兩者的區別。

 

 

1、join ()方法:主執行緒A中,建立了子執行緒B,並且在主執行緒A中呼叫了B.join(),那麼,主執行緒A會在呼叫的地方等待,直到子執行緒B完成操作後,才可以接著往下執行,那麼在呼叫這個執行緒時可以使用被呼叫執行緒的join方法。

 

原型:join([timeout])
     裡面的引數時可選的,代表執行緒執行的最大時間,即如果超過這個時間,不管這個此執行緒有沒有執行完畢都會被回收,然後主執行緒或函式都會接著執行的。

例子:

 

 

 


 
  1. import threading

  2. import time

  3. class MyThread(threading.Thread):

  4. def __init__(self,id):

  5. threading.Thread.__init__(self)

  6. self.id = id

  7. def run(self):

  8. x = 0

  9. time.sleep(10)

  10. print self.id

  11.  
  12. if __name__ == "__main__":

  13. t1=MyThread(999)

  14. t1.start()

  15. for i in range(5):

  16. print i

執行後的結果是:

 


 
  1. 0

  2. 1

  3. 2

  4. 3

  5. 4

  6. 999

機器上執行時,4和999之間,有明顯的停頓。解釋:執行緒t1 start後,主執行緒並沒有等執行緒t1執行結束後再執行,而是先把5次迴圈列印執行完畢(列印到4),然後sleep(10)後,執行緒t1把傳進去的999才列印出來。

現在,我們把join()方法加進去(其他程式碼不變),看看有什麼不一樣,例子:

 


 
  1. import threading

  2. import time

  3. class MyThread(threading.Thread):

  4. def __init__(self,id):

  5. threading.Thread.__init__(self)

  6. self.id = id

  7. def run(self):

  8. x = 0

  9. time.sleep(10)

  10. print self.id

  11.  
  12. if __name__ == "__main__":

  13. t1=MyThread(999)

  14. t1.start()

  15. t1.join()

  16. for i in range(5):

  17. print i

執行後的結果是: 

 

 


 
  1. 999

  2. 0

  3. 1

  4. 2

  5. 3

  6. 4

機器上執行時,999之前,有明顯的停頓。解釋:執行緒t1 start後,主執行緒停在了join()方法處,等sleep(10)後,執行緒t1操作結束被join,接著,主執行緒繼續迴圈列印。

 

2、setDaemon()方法。主執行緒A中,建立了子執行緒B,並且在主執行緒A中呼叫了B.setDaemon(),這個的意思是,把主執行緒A設定為守護執行緒,這時候,要是主執行緒A執行結束了,就不管子執行緒B是否完成,一併和主執行緒A退出.這就是setDaemon方法的含義,這基本和join是相反的。此外,還有個要特別注意的:必須在start() 方法呼叫之前設定,如果不設定為守護執行緒,程式會被無限掛起。

 

例子:就是設定子執行緒隨主執行緒的結束而結束:

 


 
  1. import threading

  2. import time

  3. class MyThread(threading.Thread):

  4. def __init__(self,id):

  5. threading.Thread.__init__(self)

  6. def run(self):

  7. time.sleep(5)

  8. print "This is " + self.getName()

  9.  
  10. if __name__ == "__main__":

  11. t1=MyThread(999)

  12. t1.setDaemon(True)

  13. t1.start()

  14. print "I am the father thread."

 

執行後的結果是:

 

I am the father thread.

 

可以看出,子執行緒t1中的內容並未打出。解釋:t1.setDaemon(True)的操作,將父執行緒設定為了守護執行緒。根據setDaemon()方法的含義,父執行緒列印內容後便結束了,不管子執行緒是否執行完畢了。

 

程式執行中,執行一個主執行緒,如果主執行緒又建立一個子執行緒,主執行緒和子執行緒就分兵兩路,分別執行,那麼當主執行緒完成想退出時,會檢驗子執行緒是否完成。如果子執行緒未完成,則主執行緒會等待子執行緒完成後再退出。但是有時候我們需要的是,只要主執行緒完成了,不管子執行緒是否完成,都要和主執行緒一起退出,這時就可以用setDaemon方法了。

所以,join和setDaemon的區別如上述的例子,它們基本是相反的。

--------------------- 本文來自 Darcy_zz 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/zhangzheng0413/article/details/41728869?utm_source=copy 

相關文章