溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python主線程與子線程結(jié)束順序的示例分析

發(fā)布時(shí)間:2021-08-25 09:23:16 來(lái)源:億速云 閱讀:103 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(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)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI