python中主線程與子線程的結束順序,你知道嗎?

對於程序來講,若是主進程在子進程還未結束時就已經退出,那麼Linux內核會將子進程的父進程ID改成1(也就是init進程),當子進程結束後會由init進程來回收該子進程。python

主線程退出後子線程的狀態依賴於它所在的進程,若是進程沒有退出的話子線程依然正常運轉。若是進程退出了,那麼它全部的線程都會退出,因此子線程也就退出了。
主線程退出,進程等待全部子線程執行完畢後才結束學習

進程啓動後會默認產生一個主線程,默認狀況下主線程建立的子線程都不是守護線程(setDaemon(False))。所以主線程結束後,子線程會繼續執行,進程會等待全部子線程執行完畢後才結束線程

全部線程共享一個終端輸出(線程所屬進程的終端)code

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...
...

可見父線程結束後,子線程仍在運行,此時結束進程,子線程纔會被終止
主線程結束後進程不等待守護線程完成,當即結束繼承

當設置一個線程爲守護線程時,此線程所屬進程不會等待此線程運行結束,進程將當即結束教程

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是守護線程,thread2非守護線程,所以,進程會等待thread2完成後結束,而不會等待thread1完成get

注意:子線程會繼承父線程中daemon的值,即守護線程開啓的子線程還是守護線程
主線程等待子線程完成後結束it

在線程A中使用B.join()表示線程A在調用join()處被阻塞,且要等待線程B的完成才能繼續執行

'''
遇到問題沒人解答?小編建立了一個Python學習交流QQ羣:778463939
尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書!
'''
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

主線程在執行到thread2.join()時被阻塞,等待thread2結束後纔會執行下一句

1/0 會使主線程報錯退出,且thread1設置了daemon=True,所以主線程意外退出時thread1也會當即結束。thread1.join()沒有被主線程執行

相關文章
相關標籤/搜索