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

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

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

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

例子:

import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
                self.id = id
        def run(self):
                x = 0
                time.sleep(10)
                print self.id

if __name__ == "__main__":
        t1=MyThread(999)
        t1.start()
        for i in range(5):
                print i

執行後的結果是:

0
1
2
3
4
999

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

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

import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
                self.id = id
        def run(self):
                x = 0
                time.sleep(10)
                print self.id
 
if __name__ == "__main__":
        t1=MyThread(999)
        t1.start()
        t1.join()
        for i in range(5):
                print i
執行後的結果是: 

999
0
1
2
3
4

機器上運行時,999之前,有明顯的停頓。解釋:線程t1 start後,主線程停在了join()方法處,等sleep(10)後,線程t1操作結束被join,接着,主線程繼續循環打印。

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

例子:就是設置子線程隨主線程的結束而結束:

import threading
import time
class MyThread(threading.Thread):
        def __init__(self,id):
                threading.Thread.__init__(self)
        def run(self):
                time.sleep(5)
                print "This is " + self.getName()
 
if __name__ == "__main__":
        t1=MyThread(999)
        t1.setDaemon(True)
        t1.start()
        print "I am the father thread."

執行後的結果是:

I am the father thread.

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

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

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






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章