python如何在所有线程结束后执行最后操作_Python线程的生命周期
在線程的生命周期中,從創建到執行以及最終終止,線程通常處于四種狀態之一:開始態、可調度狀態、阻塞態和終止態。
父線程和子線程
當一個新的進程或程序開始運行時,它將以一個線程開始,這個線程被稱為主線程。然后主線程可以啟動或生成其他線程,這被稱為子線程,它們同樣是進程的一部分,但獨立執行其他任務。如果需要,這些線程還可以生成自己的子線程,當每個線程完成執行時,將通知它們的父線程,最后主線程終止整個任務。父線程和子線程關系如下圖所示:
線程的四種基本狀態
不同的編程語言可能會使用不同的名稱,并且還有一些額外的名稱,但通常在線程的生命周期中,從創建到執行以及最終終止,線程通常處于四種狀態:開始態、可調度態、阻塞態和終止態。開始態:主線程需要產生或創建另一個線程來輔助完成整個任務,子線程將以新狀態開始,Python語言要求在創建線程后顯式啟動它。
可調度態:處于可運行狀態,這意味著操作系統可以安排資源調度執行。通過上下文與其他線程交換,以便在處理器上運行。
阻塞態:當線程需要等待事件發生時,如外部輸入或計時器,或者調用子線程的join()方法進入阻塞狀態,當進入阻塞態時,線程不會使用任何CPU資源。
終止態:線程在完成執行或異常中止時進入終止狀態。
線程的狀態轉換如下圖所示:
線程生命周期示例
線程的定義有兩種方式,分別是函數方式和類定義方式。函數方式在創建新線程時為它分配一個函數,即它將要執行的代碼,我們在前面的課程中已經介紹過了,感興趣的讀者請參閱《一個Python多線程運行實例》。本文演示Python線程的生命周期將使用class方式來定義線程,具體代碼如下:
#!/usr/bin/env python3
""" Two threads cooking soup """
import threading
import time
class ChefOlivia(threading.Thread):
def __init__(self):
super(ChefOlivia, self).__init__()
def run(self):
print('Olivia started & waiting for sausage to thaw...')
time.sleep(3)
print('Olivia is done cutting sausage.')
# main thread a.k.a Barron
if __name__ == '__main__':
print("Barron started & requesting Olivia's help.")
olivia = ChefOlivia()
print(" Olivia alive?", olivia.is_alive())
print("Barron tells Olivia to start.")
olivia.start()
print(" Olivia alive?", olivia.is_alive())
print("Barron continues cooking soup.")
time.sleep(0.5)
print(" Olivia alive?", olivia.is_alive())
print("Barron patiently waits for Olivia to finish and join...")
olivia.join()
print(" Olivia alive?", olivia.is_alive())
print("Barron and Olivia are both done!")
這個示例程序,模擬了Olivia和Barraon之間線程協作,Olivia需要幫助完成切片香腸,最后Brrraon完成做湯的算法。在Python中通過類創建線程需要定義一個繼承threading.Thread類的子類,并且需要重載init和 run方法,在本例的init方法中,只需使用super函數執行父線程初始化即可。
首先Barron啟動并請求Olivia的幫助,然后創建一個新的ChefOlivia對象。此時ChefOlivia還沒有開始,Barron顯示調用Olivia的start()方法啟動子線程。然后Barron繼續煮湯,并花費了0.5秒鐘的時候。因為Olivia切香腸需要3秒鐘時間,Barron會在其之前完成,為了最終完成整個做湯的任務,Barron會同步等待Olivia,通過調用join()方法,主線程進入阻塞狀態,直到Olivia完成任務后,最后程序終止。
回到代碼中,我們在控制臺中運行此程序,同時加入了判斷Olivia狀態的打印語句,is_alive方法返回一個布爾值,指示該線程當前狀態。最終打印結果輸出如下:
$ python thread_lifecycle.py
Barron started & requesting Olivia's help.
Olivia alive? False
Barron tells Olivia to start.
Olivia started & waiting for sausage to thaw...
Olivia alive? True
Barron continues cooking soup.
Olivia alive? True
Barron patiently waits for Olivia to finish and join...
Olivia is done cutting sausage.
Olivia alive? False
Barron and Olivia are both done!
注意Olivia的線程在最初創建后并沒有啟動,狀態顯示是False,需要Barron線程顯示調用start方法,之后線程狀態顯示存活。Olivia的線程正sleeping時,Python認為子線程狀態仍然是存活的。Olivia調用join,主線程進入阻塞,并等待子線程其完成,Olivia運行完成,主線程繼續執行,直至整個程序結束。整個程序的生命周期狀態如下圖所示:
結束語
本文介紹了主線程和子線程的關系,以及線程在操作系統中的四種基本狀態,講解了除了使用函數定義線程之外,使用class定義子線程的方法,最后展示了一個線程的生命周期代碼實例。
總結
以上是生活随笔為你收集整理的python如何在所有线程结束后执行最后操作_Python线程的生命周期的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python pd Series 添加行
- 下一篇: python常用包数据分析_数据分析领域