Python中threading的join和setDaemon的區別[帶例子]


python的進程和線程經常用到,之前一直不明白threading的join和setDaemon的區別和用法,今天特地研究了一下。multiprocessing中也有這兩個方法,同樣適用,這里以threading的join和setDaemon舉例。

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

原型:join([timeout])

里面的參數時可選的,代表線程運行的最大時間,即如果超過這個時間,不管這個此線程有沒有執行完畢都會被回收,然后主線程或函數都會接着執行的。

例子:

# -*- coding: utf-8 -*-

from threading import Thread
from time import sleep

def search():
    sleep(5)
    print 2

if __name__ == '__main__':
    t = Thread(target=search)
    t.start()
    # t.join()
    print 1

執行后的結果:

1
2

運行后,當打印完1停頓了5秒后才打印2。解釋:線程t開始后,需要睡5s,主線程並沒有等待線程t執行完,就開始往下執行。

現在,我們把t.join()注釋去掉(其他代碼不變),看看有什么變化,例子:

# -*- coding: utf-8 -*-

from threading import Thread
from time import sleep

def search():
    sleep(5)
    print 2

if __name__ == '__main__':
    t = Thread(target=search)
    t.start()
    t.join()
    print 1

 

執行后的結果:

2
1

運行后,發現停頓了5秒后才打印2,然后立即打印了1。解釋:當程序運行到t.join()時,停在了t.join()處,等待線程t執行完,然后開始往下執行。

2.

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

例子:

from threading import Thread
from time import sleep

def search():
    for i in range(5):
        sleep(1)
        print 2

if __name__ == '__main__':
    t = Thread(target=search)
    # t.setDaemon(True)
    t.start()
    print 1

 

執行后的結果:

1
2
2
2
2
2

運行過程中,程序還沒運行完時,關閉程序。會發現程序還在打印2。這是因為主線程默認等待線程t執行完才關閉,主線程執行完,子線程t沒有執行完,程序就被掛起,一直等待子線程執行完畢。

現在,我們把t.setDaemon(True)的注釋刪掉,再執行查看結果。例子:

# -*- coding: utf-8 -*-

from threading import Thread
from time import sleep

def search():
    for i in range(5):
        sleep(1)
        print 2

if __name__ == '__main__':
    t = Thread(target=search)
    t.setDaemon(True)
    t.start()
    print 1

執行結果:

1

執行發現,程序在打印完1后就停止了。這是因為主線程執行完以后,不再等待子線程是否執行完,立馬結束。

threading的join和setDaemon的區別總結:如果主線程中調用了join(),程序會阻塞在調用處,直到子線程執行完才往下執行。如果沒調用,主線程則無需等待,直接往下執行。如果主線程中調用了setDaemon(True),則當程序關閉或者執行完后,子線程立馬關閉,不管其是否執行完。如果主線程中沒有調用setDaemon(True),則當程序關閉或者執行完后,子線程會繼續執行,直到執行完。join管阻塞,setDaemon管結束。

正常開發中,當開啟了多線程,為了不讓程序阻塞,同時主線程關閉時,子線程能夠都同時關閉,會用下面的方法。

# -*- coding: utf-8 -*-

from threading import Thread
from time import sleep

def search():
    for i in range(5):
        sleep(1)
        print 2

def insert():
    for i in range(5):
        sleep(0.9)
        print 3

if __name__ == '__main__':
    task1 = Thread(target=search)
    task2 = Thread(target=insert)
    task1.setDaemon(True)
    task2.setDaemon(True)
    task1.start()
    task2.start()
    while True:
        sleep(10)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM