您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)python主線程與子線程結(jié)束順序的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
引用自 主線程退出對(duì)子線程的影響 的一段話:
對(duì)于程序來(lái)說(shuō),如果主進(jìn)程在子進(jìn)程還未結(jié)束時(shí)就已經(jīng)退出,那么Linux內(nèi)核會(huì)將子進(jìn)程的父進(jìn)程ID改為1(也就是init進(jìn)程),當(dāng)子進(jìn)程結(jié)束后會(huì)由init進(jìn)程來(lái)回收該子進(jìn)程。
主線程退出后子線程的狀態(tài)依賴于它所在的進(jìn)程,如果進(jìn)程沒(méi)有退出的話子線程依然正常運(yùn)轉(zhuǎn)。如果進(jìn)程退出了,那么它所有的線程都會(huì)退出,所以子線程也就退出了。
主線程退出,進(jìn)程等待所有子線程執(zhí)行完畢后才結(jié)束
進(jìn)程啟動(dòng)后會(huì)默認(rèn)產(chǎn)生一個(gè)主線程,默認(rèn)情況下主線程創(chuàng)建的子線程都不是守護(hù)線程(setDaemon(False))。因此主線程結(jié)束后,子線程會(huì)繼續(xù)執(zhí)行,進(jìn)程會(huì)等待所有子線程執(zhí)行完畢后才結(jié)束
所有線程共享一個(gè)終端輸出(線程所屬進(jìn)程的終端)
import threading import time def child_thread1(): for i in range(100): time.sleep(1) print('child_thread1_running...') def parent_thread(): print('parent_thread_running...') thread1 = threading.Thread(target=child_thread1) thread1.start() print('parent_thread_exit...') if __name__ == "__main__": parent_thread()
輸出為:
parent_thread_running... parent_thread_exit... child_thread1_running... child_thread1_running... child_thread1_running... child_thread1_running... ...
可見(jiàn)父線程結(jié)束后,子線程仍在運(yùn)行,此時(shí)結(jié)束進(jìn)程,子線程才會(huì)被終止
主線程結(jié)束后進(jìn)程不等待守護(hù)線程完成,立即結(jié)束
當(dāng)設(shè)置一個(gè)線程為守護(hù)線程時(shí),此線程所屬進(jìn)程不會(huì)等待此線程運(yùn)行結(jié)束,進(jìn)程將立即結(jié)束
import threading import time def child_thread1(): for i in range(100): time.sleep(1) print('child_thread1_running...') def child_thread2(): for i in range(5): time.sleep(1) print('child_thread2_running...') def parent_thread(): print('parent_thread_running...') thread1 = threading.Thread(target=child_thread1) thread2 = threading.Thread(target=child_thread2) thread1.setDaemon(True) thread1.start() thread2.start() print('parent_thread_exit...') if __name__ == "__main__": parent_thread()
輸出:
parent_thread_running... parent_thread_exit... child_thread1_running...child_thread2_running... child_thread1_running...child_thread2_running... child_thread1_running...child_thread2_running... child_thread1_running...child_thread2_running... child_thread2_running...child_thread1_running... Process finished with exit code 0
thread1是守護(hù)線程,thread2非守護(hù)線程,因此,進(jìn)程會(huì)等待thread2完成后結(jié)束,而不會(huì)等待thread1完成
注意:子線程會(huì)繼承父線程中daemon的值,即守護(hù)線程開(kāi)啟的子線程仍是守護(hù)線程
主線程等待子線程完成后結(jié)束
在線程A中使用B.join()表示線程A在調(diào)用join()處被阻塞,且要等待線程B的完成才能繼續(xù)執(zhí)行
import threading import time def child_thread1(): for i in range(10): time.sleep(1) print('child_thread1_running...') def child_thread2(): for i in range(5): time.sleep(1) print('child_thread2_running...') def parent_thread(): print('parent_thread_running...') thread1 = threading.Thread(target=child_thread1) thread2 = threading.Thread(target=child_thread2) thread1.setDaemon(True) thread2.setDaemon(True) thread1.start() thread2.start() thread2.join() 1/0 thread1.join() print('parent_thread_exit...') if __name__ == "__main__": parent_thread()
輸出:
parent_thread_running... child_thread1_running... child_thread2_running... child_thread1_running... child_thread2_running... child_thread1_running... child_thread2_running... child_thread1_running... child_thread2_running... child_thread1_running... child_thread2_running... Traceback (most recent call last): File "E:/test_thread.py", line 31, in <module> parent_thread() File "E:/test_thread.py", line 25, in parent_thread 1/0 ZeroDivisionError: integer division or modulo by zero
主線程在執(zhí)行到thread2.join()時(shí)被阻塞,等待thread2結(jié)束后才會(huì)執(zhí)行下一句
1/0 會(huì)使主線程報(bào)錯(cuò)退出,且thread1設(shè)置了daemon=True,因此主線程意外退出時(shí)thread1也會(huì)立即結(jié)束。thread1.join()沒(méi)有被主線程執(zhí)行
關(guān)于“python主線程與子線程結(jié)束順序的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。