Linux之進程狀態(tài)&&進程優(yōu)先級詳解
一、操作系統(tǒng)的進程狀態(tài)
1.1運行狀態(tài)
- 當一個進程準備就緒,獲得了CPU資源,就會在CPU所維護的運行隊列上等待CPU的調(diào)度
- 一個進程在運行或者處于運行隊列中,都叫做運行狀態(tài)
- 一個進程并不是一直在CPU上執(zhí)行的,而是會以進程切換的方式,在一段時間內(nèi),使多個進程同時被推進---并發(fā)
- CPU對進程的調(diào)度是基于進程切換和時間片輪轉(zhuǎn)的調(diào)度算法
1.2阻塞狀態(tài)
- 當一個進程正在等待某種IO事件的完成,實際上就是在等待獲取某種資源,那么該進程就處于一種阻塞狀態(tài)
- 操作系統(tǒng)對軟硬件資源進行管理,都要遵循“先描述再組織”的原則,操作系統(tǒng)對外設(shè)的管理就是在內(nèi)存中創(chuàng)建一個個的外設(shè)數(shù)據(jù)結(jié)構(gòu)對象,再用鏈表的方式組織起來
- 每一個外設(shè)的pcb數(shù)據(jù)結(jié)構(gòu)對象都會包含一個等待隊列,當一個進程在獲取某種外設(shè)資源時(比如scanf),外設(shè)資源還未準備好,該進程就會鏈入該外設(shè)的pcb等待隊列進行等待,此時進程就處于阻塞狀態(tài),直到資源準備就緒,才會被鏈入運行隊列等待CPU調(diào)度,將狀態(tài)S改為R
1.3掛起
- 當進程在隊列中排隊,操作系統(tǒng)的資源嚴重不足或者操作系統(tǒng)需要給新加入的進程提供空間,那么此時操作系統(tǒng)就會將正在等待排隊的進程所對應的數(shù)據(jù)和代碼換出到外設(shè)分區(qū)中,等到該進程被調(diào)度了再換入給該進程
- 從換出到換出的過程,進程處于掛起狀態(tài)
二、Linux下具體的狀態(tài)
static const char * const task_state_array[] = { "R (running)", /* 0 */ "S (sleeping)", /* 1 */ "D (disk sleep)", /* 2 */ "T (stopped)", /* 4 */ "t (tracing stop)", /* 8 */ "X (dead)", /* 16 */ "Z (zombie)", /* 32 */ };
- R就是操作系統(tǒng)中進程的運行狀態(tài):并不意味著該進程一定在運行中,它表明該進程要么在運行要么在運行隊列中
- S和D狀態(tài)都對應操作系統(tǒng)中的阻塞狀態(tài):S是一種淺度睡眠,可以被喚醒;D是一種深度睡眠,不會響應任何請求
- 當一個進程正在進行某種IO事件,比如在向磁盤寫入重要數(shù)據(jù)的時候,它必須等待磁盤寫入完畢將寫入結(jié)果反饋給進程,再反饋給上層用戶,但如果這時候操作系統(tǒng)的資源嚴重不足,進程掛起已經(jīng)沒辦法解決問題了,操作系統(tǒng)就會選擇殺掉進程,如果一個進程在等待磁盤寫入完畢的期間被殺掉,那么就會導致數(shù)據(jù)的丟失!為了防止這種情況,必須給該進程一個標識符--D,告訴操作系統(tǒng)我這個進程在等待磁盤寫入完畢的期間是不能被殺掉的
- T停止狀態(tài):可以通過發(fā)送SIGSTOP來停止進程,可以發(fā)送SIGCONT來讓進程繼續(xù)運行,當一個進程想要獲取某種資源或者被其他進程控制(如gdb),就可能會出現(xiàn)T狀態(tài)
- R就是操作系統(tǒng)中進程的運行狀態(tài):并不意味著該進程一定在運行中,它表明該進程要么在運行要么在運行隊列中
- S和D狀態(tài)都對應操作系統(tǒng)中的阻塞狀態(tài):S是一種淺度睡眠,可以被喚醒;D是一種深度睡眠,不會響應任何請求
- 當一個進程正在進行某種IO事件,比如在向磁盤寫入重要數(shù)據(jù)的時候,它必須等待磁盤寫入完畢將寫入結(jié)果反饋給進程,再反饋給上層用戶,但如果這時候操作系統(tǒng)的資源嚴重不足,進程掛起已經(jīng)沒辦法解決問題了,操作系統(tǒng)就會選擇殺掉進程,如果一個進程在等待磁盤寫入完畢的期間被殺掉,那么就會導致數(shù)據(jù)的丟失!為了防止這種情況,必須給該進程一個標識符--D,告訴操作系統(tǒng)我這個進程在等待磁盤寫入完畢的期間是不能被殺掉的
- T停止狀態(tài):可以通過發(fā)送SIGSTOP來停止進程,可以發(fā)送SIGCONT來讓進程繼續(xù)運行,當一個進程想要獲取某種資源或者被其他進程控制(如gdb),就可能會出現(xiàn)T狀態(tài)
子進程退出,父進程沒有退出并且沒有回收子進程的退出信息,就會使子進程進入僵尸進程
- 孤兒進程:當子進程還沒退出,父進程就已經(jīng)推出了,那么該子進程就會被1號進程(操作系統(tǒng))領(lǐng)養(yǎng),此時的子進程就叫做孤兒進程。
- 為什么要被1號進程領(lǐng)養(yǎng)?
- 為了讓子進程在退出的時候可以被回收退出信息。此時退出進程不能再用Ctrl C 而應該使用kill -9 殺掉進程
三、進程的優(yōu)先級
3.1基本概念
- CPU的資源是有限的,但是進程是多個的,這就注定了進程之間存在競爭關(guān)系
- 為了保證進程被CPU調(diào)度的公平和良性競爭,就必須引入進程優(yōu)先級的概念
- 進程優(yōu)先級是指CPU分配資源的先后順序(訪問資源的先后順序)
- 如果一個進程長時間無法訪問到資源,代碼無法被推進,就會導致該進程的饑餓問題
- 優(yōu)先權(quán)高的進程有優(yōu)先執(zhí)行權(quán)利。配置進程優(yōu)先權(quán)對多任務環(huán)境的linux很有用,可能改善系統(tǒng)性能
- 還可以把進程運行到指定的CPU上,這樣一來,把不重要的進程安排到某個CPU,可以大大改善系統(tǒng)整 體性能
3.2查看進程優(yōu)先級的命令
- 使用 ps -al
UID
: 代表執(zhí)行者的身份PID
: 代表這個進程的代號PPID
:代表這個進程是由哪個進程發(fā)展衍生而來的,亦即父進程的代號PRI
:代表這個進程可被執(zhí)行的優(yōu)先級,其值越小越早被執(zhí)行NI
:代表這個進程的 nice 值
PRI即進程的優(yōu)先級,通俗點說就是程序被CPU執(zhí)行的先后順序,此值越小
進程的優(yōu)先級別越高(默認80)
NI就是nice值,其表示進程可被執(zhí)行的優(yōu)先級的修正數(shù)值
PRI值越小越快被執(zhí)行,那么加入nice值后,將會使得PRI變?yōu)椋篜RI(new)=PRI(old)+nice
這樣,當nice值為負值的時候,那么該程序?qū)?yōu)先級值將變小,即其優(yōu)先級會變高,則其越快被執(zhí)行
所以,調(diào)整進程優(yōu)先級,在Linux下,就是調(diào)整進程nice值 ,Linux為了保證優(yōu)先級的調(diào)整范圍,nice其取值范圍是-20至19,一共40個級別
3.3修改進程優(yōu)先級的命令
- 使用top r + 進程pid + 修正的nice值
操作系統(tǒng)是如何根據(jù)優(yōu)先級展開調(diào)度的呢?
CPU會維護一個runqueue,runqueue中有兩個調(diào)度隊列,他們本質(zhì)上是兩個指針數(shù)組,存儲40個優(yōu)先級所一一對應的40個隊列的指針,再結(jié)合位圖的思想(調(diào)度完畢的隊列為0,未調(diào)度完畢的隊列為1),針對不同的優(yōu)先級對進程進行調(diào)度!
新加入的進程或者被進程切換下來的進程會鏈接到另外一個調(diào)度隊列的對應的優(yōu)先級的隊列當中去,直到前一個調(diào)度隊列全部調(diào)度完后,swap交換兩個隊列的指針,對另外一個未調(diào)度的隊列進行調(diào)度,以此循環(huán)往復,也叫Linux內(nèi)核的O(1)調(diào)度算法
3.4其他概念
- 競爭性: 系統(tǒng)進程數(shù)目眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高效完成任務,更合理競爭相關(guān)資源,便具有了優(yōu)先級
- 獨立性: 多進程運行,需要獨享各種資源,多進程運行期間互不干擾
- 并行: 多個進程在多個CPU下分別,同時進行運行,這稱之為并行
- 并發(fā): 多個進程在一個CPU下采用進程切換的方式,在一段時間之內(nèi),讓多個進程都得以推進,稱之為并發(fā)
3.5并發(fā)
- 函數(shù)的返回值是如何被外部拿到的?----通過CPU寄存器
- 系統(tǒng)如何得知我們當前進程執(zhí)行到哪一行代碼?----通過pc(eip)程序計數(shù)器,記錄當前進程執(zhí)行的指令的下一條指令的地址
- CPU中的寄存器很多!將進程中的高頻數(shù)據(jù)放入到CPU的寄存器中可以提高效率
- 問題是,我們在進行進程切換到時候,如果不把屬于當前進程的存儲在寄存器中的數(shù)據(jù)帶走,那么下一個來的進程在把數(shù)據(jù)放入寄存器的時候就會將上一個進程的數(shù)據(jù)覆蓋,等到該進程重新被CPU調(diào)度,就無法從上一次執(zhí)行的位置繼續(xù)往下執(zhí)行
- CPU的寄存器中保存的是進程的臨時數(shù)據(jù),也叫進程的上下文
- 一個進程在被CPU高頻調(diào)度的時候,必須經(jīng)歷調(diào)度----排隊,在這個過程中,進程離開CPU必須自己保存上下文帶走,再被調(diào)度時恢復上下文
- 總之,進程切換涉及到保存上下文和恢復上下文,寄存器中的數(shù)據(jù)在被保存時實際上是以結(jié)構(gòu)體的形式被保存在內(nèi)存中,進程的pcb數(shù)據(jù)結(jié)構(gòu)對象中存在一個指向該結(jié)構(gòu)體的指針
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何使用win10內(nèi)置的linux系統(tǒng)啟動spring-boot項目
這篇文章主要介紹了如何使用​win10內(nèi)置的linux系統(tǒng)啟動spring-boot項目,需要的朋友可以參考下2020-07-07Ubuntu無網(wǎng)絡(luò)連接及標識的解決方法
本文已解決 Ubuntu無網(wǎng)絡(luò)連接/無網(wǎng)絡(luò)標識解決方法的相關(guān)問題,并總結(jié)提出了幾種可用解決方案,如果有遇到相同問題的朋友可以參考閱讀下本文,對解決問題有一定的幫助2024-09-09Centos7的apache網(wǎng)站環(huán)境搭建wordpress
本篇文章給大家詳細分析了在Centos7的apache網(wǎng)站環(huán)境搭建wordpress的詳細操作方法,有興趣的朋友參考下。2018-02-02