進程狀態
Linux進程狀態
Linux進程狀態 | 進程描述 |
R | 運行狀態 |
S | 睡眠狀態 |
D | 磁盤休眠狀態 |
T | 停止狀態 |
t | 被追蹤狀態(調試狀態) |
X | 死亡狀態 |
Z | 僵死狀態 |
其實大致也就可以分為三種運行,阻塞,掛起。
運行狀態
每個cpu里都有一個運行隊列,進程在運行隊列里,不管他是否正在被運行。這種進程就屬于運行狀態,也就是運行態,在Linux系統中就是R狀態。cpu里有一個函數叫調度器,當一個進程要運行的時候,有調度器上傳,cpu既可以運行該進程了。一個進程不是在cpu里一直運行,直到該進程運行完畢。而是運行一段時間,無論你是否運行完畢,都要退出。這個時間叫時間片。假設時間片是10毫秒,每個進程都只能運行10毫秒,然后后下來排隊,其他進程運行。所以,在一段時間內,每個進程都可以運行。這種情況叫并發執行,一個cpu,一段時間內,多個進程都運行了。大量把進程從cpu上拿下來,放上去,就叫進程切換,
阻塞狀態
當一個進程為了等待某種資源時,而處于等待狀態的進程就屬于阻塞狀態,一般是放到等待隊列里。比如一個進程需要等待鍵盤設備,操作系統考慮到既然該進程需要依靠其他進程或者數據等才能運行,就不會把它放到運行隊列中。而是會把它放到等待隊列中,直到他需要的進程或者數據等準備好了,才會把該進程放到運行隊列。此時該進程的狀態就是,阻塞狀態。
掛起狀態
還是剛剛,那個情景,該進程需要等待鍵盤外設,可是突然內存資源嚴重不足。操作系統就會把該進程的代碼和數據放到磁盤上,減輕內存壓力,只保留PCB。此時該進程的狀態就是掛起狀態,更準確說是阻塞掛起狀態,因為PCB還是保留在等待隊列中。有些地方會把掛起狀態進行很多分類。其實,都是掛起狀態,記一個就好。當一個進程的PCB保留在內存中,代碼和數據卻在磁盤上,此時該進程就是掛起狀態。
接下來我們看看Linux進程狀態的分類
R,運行狀態,一般情況是查不到這個狀態的。因為CPU的運行特別塊,你幾乎察覺不到,是瞬時的。
S和D分別時淺度睡眠和深度睡眠兩種狀態,淺度睡眠可以被喚醒,深度睡眠除了斷電沒有辦法阻止。咱們先不管他是什么深淺睡眠,既然是睡眠狀態,那就表明該進程目前不運行,當這個進程是為了等待某種資源而進入睡眠,那他就是阻塞狀態。但是,如果他就是單純的進入睡眠狀態,不是為了等待某種資源,那他就是普通睡眠狀態。
sleep(1)
使用sleep函數可以使進程進入淺度睡眠
那什么是深度睡眠呢?深度睡眠是指當進程在執行某項重要任務時,不可以突然的終止執行,為了防止資源泄露等問題,給該進程了一種權限,誰也不可以終止該進程,直到該進程運行完畢,即使該進程為了等待硬件的資源,而處于等待隊列里,也不可以終止該進程。比如,io流輸出的時候,向磁盤寫入的時候。注意,操作系統也不可以終止該進程。
T和t兩種狀態分別是停止狀態和被追蹤停止狀態,T狀態可以通過SIGSTOP信號停止進程,通過SIGCONT信號繼續運行。t狀態,一般就是gdb調式的時候,可以任意打斷點,停止進程。
X是死亡狀態,就是進程被殺死時狀態,是瞬時的,一般查不到。Z是僵尸狀態,當一個進程結束運行時,會短暫處于這個狀態,等待父進程回收。如果,該父進程一直不回收,那子進程就一直處于Z狀態,該進程也叫僵尸進程,操作系統會一直維護這個進程,如果僵尸進程過多,就會導致內存資源浪費,內存泄漏,等等
孤兒進程
當一個子進程的父進程提前退出,而子進程卻在運行的時候,此時,該進程就是孤兒進程。因為他沒有父進程回收,這會導致內存泄漏。操作系統為了處理這個麻煩,就會讓1號進程回收該進程,比如bash命令行。
進程的其他概念
競爭性:系統進程數目眾多,而CPU資源只有少量,甚至1個,所以進程之間是具有競爭屬性的。為了高 效完成任務,更合理競爭相關資源,便具有了優先級
獨立性:多進程運行,需要獨享各種資源,多進程運行期間互不干擾
并發:多個進程在1個cpu采取進程切換,在一段時間內,讓多個進程得以推進
進程切換,使用到兩個隊列,當時間片完,一個進程無論是否執行完,都要切換另一個隊列。
并行:多個進程在多個cpu同時進行
cpu里的寄存器
兩個問題:
函數返回值如何獲取?通過寄存器存儲,獲取。
系統如何得知進程執行情況?程序計數器pc,eip記錄進程執行指令的下一行指令地址。本質是寄存器
常見寄存器有:eax,ecx,ebx,edx
關于棧的寄存器有:ebp,esp
指令寄存器:eip
cpu里的寄存器,記錄正在運行的進程數據。我們把這種數據叫做上下文。簡單說就是,上下文就是寄存器記錄的進程相關數據。
當進程退出的時候,需要把他的上下文數據保存并帶走。保存的目的是為了恢復,因為進程再次運行的時候,需要從上次運行的地方繼續運行。