python 線程的五個(gè)狀態(tài)
當(dāng)程序中包含多個(gè)線程時(shí),CPU 不是一直被特定的線程霸占,而是輪流執(zhí)行各個(gè)線程。
那么,CPU 在輪換執(zhí)行線程的過程中,即從創(chuàng)建到消亡的整個(gè)過程,可能會(huì)歷經(jīng) 5 種狀態(tài),分別是新建、就緒、運(yùn)行、阻塞和死亡。
線程的新建狀態(tài)
無論是通過 Thread 類直接實(shí)例化對象創(chuàng)建線程,還是通過繼承自 Thread 類的子類實(shí)例化創(chuàng)建線程,新創(chuàng)建的線程在調(diào)用 start() 方法之前,不會(huì)得到執(zhí)行,此階段的線程就處于新建狀態(tài)。
線程的就緒狀態(tài)
當(dāng)位于新建狀態(tài)的線程調(diào)用 start() 方法后,該線程就轉(zhuǎn)換到就緒狀態(tài)。
所謂就緒,就是告訴 CPU,該線程已經(jīng)可以執(zhí)行了,但是具體什么時(shí)候執(zhí)行,取決于 CPU 什么時(shí)候調(diào)度它。
換句話說,如果一個(gè)線程處于就緒狀態(tài),只能說明此線程已經(jīng)做好了準(zhǔn)備,隨時(shí)等待 CPU 調(diào)度執(zhí)行,并不是說執(zhí)行了 start() 方法此線程就會(huì)立即被執(zhí)行。
線程的運(yùn)行狀態(tài)
當(dāng)位于就緒狀態(tài)的線程得到了 CPU,并開始執(zhí)行 target 參數(shù)執(zhí)行的目標(biāo)函數(shù)或者 run() 方法,就表明當(dāng)前線程處于運(yùn)行狀態(tài)。
但如果當(dāng)前有多個(gè)線程處于就緒狀態(tài)(等待 CPU 調(diào)度)時(shí),處于運(yùn)行狀態(tài)的線程將無法一直霸占 CPU 資源,為了使其它線程也有執(zhí)行的機(jī)會(huì),CPU 會(huì)在一定時(shí)間內(nèi)強(qiáng)制當(dāng)前運(yùn)行的線程讓出 CPU 資源,以供其他線程使用。
線程的阻塞狀態(tài)
當(dāng) CPU 對多個(gè)線程進(jìn)行調(diào)度時(shí),對于獲得 CPU 調(diào)度卻沒有執(zhí)行完畢的線程,就會(huì)進(jìn)入阻塞狀態(tài)。
目前幾乎所有的桌面和服務(wù)器操作系統(tǒng),都采用的是搶占式優(yōu)先級調(diào)度策略。即 CPU 會(huì)給每一個(gè)就緒線程一段固定時(shí)間來處理任務(wù),當(dāng)該時(shí)間用完后,系統(tǒng)就會(huì)阻止該線程繼續(xù)使用 CPU 資源,讓其他線程獲得執(zhí)行的機(jī)會(huì)。
對于具體選擇那個(gè)線程上 CPU,不同的平臺采用不同的算法,比如先進(jìn)先出算法(FIFO)、時(shí)間片輪轉(zhuǎn)算法、優(yōu)先級算法等,每種算法各有優(yōu)缺點(diǎn),適用于不同的場景。
除此之外,如果處于運(yùn)行狀態(tài)的線程發(fā)生如下幾種情況,也將會(huì)由運(yùn)行狀態(tài)轉(zhuǎn)到阻塞狀態(tài):
- 線程調(diào)用了 sleep() 方法;
- 線程等待接收用戶輸入的數(shù)據(jù);
- 線程試圖獲取某個(gè)對象的同步鎖時(shí),如果該鎖被其他線程所持有,則當(dāng)前線程進(jìn)入阻塞狀態(tài);
- 線程調(diào)用 wait() 方法,等待特定條件的滿足。
以上幾種情況都會(huì)導(dǎo)致線程阻塞,只有解決了線程遇到的問題之后,該線程才會(huì)由阻塞狀態(tài)轉(zhuǎn)到就緒狀態(tài),繼續(xù)等待 CPU 調(diào)度。
以上 4 種可能發(fā)生線程阻塞的情況,解決措施分別如下:
- sleep() 方法規(guī)定的時(shí)間已過;
- 線程接收到了用戶輸入的數(shù)據(jù);
- 其他線程釋放了該同步鎖,并由該線程獲得;
- 調(diào)用 set() 方法發(fā)出通知。
線程死亡狀態(tài)
對于獲得 CPU 調(diào)度卻未執(zhí)行完畢的線程,它會(huì)轉(zhuǎn)入阻塞狀態(tài),待條件成熟之后繼續(xù)轉(zhuǎn)入就緒狀態(tài),重復(fù)爭取 CPU 資源,直到其執(zhí)行結(jié)束。
執(zhí)行結(jié)束的線程將處于死亡狀態(tài)。
線程執(zhí)行結(jié)束,除了正常執(zhí)行結(jié)束外,如果程序執(zhí)行過程發(fā)生異常(Exception)或者錯(cuò)誤(Error),線程也會(huì)進(jìn)入死亡狀態(tài)。
對于處于死亡狀態(tài)的線程,有以下 2 點(diǎn)需要注意:
- 主線程死亡,并不意味著所有線程全部死亡。也就是說,主線程的死亡,不會(huì)影響子線程繼續(xù)執(zhí)行;反之也是如此。
- 對于死亡的線程,無法再調(diào)用 start() 方法使其重新啟動(dòng),否則 Python 解釋器將拋出 RuntimeError 異常。
以上就是python 線程的五個(gè)狀態(tài)的詳細(xì)內(nèi)容,更多關(guān)于python 線程狀態(tài)的資料請關(guān)注腳本之家其它相關(guān)文章!
- Python實(shí)現(xiàn)線程狀態(tài)監(jiān)測簡單示例
- python利用線程實(shí)現(xiàn)多任務(wù)
- python 多線程死鎖問題的解決方案
- 實(shí)例代碼講解Python 線程池
- 區(qū)分python中的進(jìn)程與線程
- python多線程semaphore實(shí)現(xiàn)線程數(shù)控制的示例
- Python多線程的退出控制實(shí)現(xiàn)
- Python QTimer實(shí)現(xiàn)多線程及QSS應(yīng)用過程解析
- 詳解Python多線程下的list
- python 使用多線程創(chuàng)建一個(gè)Buffer緩存器的實(shí)現(xiàn)思路
- Python logging模塊異步線程寫日志實(shí)現(xiàn)過程解析
相關(guān)文章
Python的網(wǎng)絡(luò)編程庫Gevent的安裝及使用技巧
Gevent庫的奧義在于并發(fā)式的高性能網(wǎng)絡(luò)程序設(shè)計(jì)支持,這里我們將來講解Python的網(wǎng)絡(luò)編程庫Gevent的安裝及使用技巧,來看一下Gevent支持的多進(jìn)程程序編寫:2016-06-06Python常用列表數(shù)據(jù)結(jié)構(gòu)小結(jié)
這篇文章主要介紹了Python常用列表數(shù)據(jù)結(jié)構(gòu)小結(jié),很有參考借鑒價(jià)值,需要的朋友可以參考下2014-08-08python實(shí)現(xiàn)斐波那契遞歸函數(shù)的方法
這篇文章主要介紹了python實(shí)現(xiàn)斐波那契遞歸函數(shù)的方法,通過一個(gè)非常簡單的遞歸函數(shù)加以實(shí)現(xiàn),需要的朋友可以參考下2014-09-09深入分析在Python模塊頂層運(yùn)行的代碼引起的一個(gè)Bug
幾個(gè)星期前, 我的同事跑過來, 說發(fā)現(xiàn)一個(gè)奇怪的Bug: 在使用Python的subprocess運(yùn)行子進(jìn)程時(shí), 當(dāng)子進(jìn)程運(yùn)行失敗時(shí)居然沒有拋出錯(cuò)誤!2014-07-07python光學(xué)仿真實(shí)現(xiàn)光線追跡之空間關(guān)系
這篇文章主要介紹了python光學(xué)仿真中實(shí)現(xiàn)光線追跡的空間關(guān)系示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10Python3 全自動(dòng)更新已安裝的模塊實(shí)現(xiàn)
這篇文章主要介紹了Python3 全自動(dòng)更新已安裝的模塊實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Python調(diào)用高德API實(shí)現(xiàn)批量地址轉(zhuǎn)經(jīng)緯度并寫入表格的功能
這篇文章主要介紹了Python調(diào)用高德API實(shí)現(xiàn)批量地址轉(zhuǎn)經(jīng)緯度并寫入表格的功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Python獲取系統(tǒng)默認(rèn)字符編碼的方法
這篇文章主要介紹了Python獲取系統(tǒng)默認(rèn)字符編碼的方法,涉及Python中sys模塊getdefaultencoding方法的使用技巧,需要的朋友可以參考下2015-06-06