讓我們深入探討linux中的進程概念,包括運行、阻塞、掛起狀態,以及pcb內核鏈表和進程狀態的詳細解釋。
1. 概念詳解
運行、阻塞、掛起狀態
內容基礎:方框中的是調度隊列,是一個雙向隊列,每一個元素是由PCB及其對應的代碼數據組成的。
-
運行:只要進程在調度隊列中,其狀態就是運行(running)。
-
阻塞:阻塞狀態是指進程在等待某種硬件資源就緒(例如網卡、鍵盤等)。
在操作系統中,除了調度隊列(runqueue)外,還有設備隊列(device queue)用于管理設備。設備隊列中包含等待隊列(wait queue)。如果某個進程在調度隊列中需要從鍵盤讀取數據,但鍵盤沒有響應,CPU會將該進程從調度隊列中移除,并將其鏈接到對應硬件的等待隊列中。這就是阻塞的過程。
- 掛起:掛起的本質是將數據交換到磁盤中的交換區(swap partition),通常在內存資源不足時發生。
當內存資源不足時,如果進程處于阻塞狀態,系統會將進程的數據交換到硬盤的交換分區,保留PCB。當內存資源充足時,數據會從交換分區被喚出,并與PCB重新組合成進程,這就是阻塞掛起。運行掛起的情況類似。
2. PCB內核鏈表的理解
這是普通的雙端隊列,可以看到next指針指向下一個元素的頭,prev指針指向上一個元素的頭。
PCB中的next指針直接指向下一個元素的next,prev指針直接指向上一個元素的prev。
一個PCB可以隸屬于多個數據結構,可以屬于調度隊列、等待隊列,也可以屬于設備隊列。因此,PCB可能有多個next和prev指針。
2. 進程狀態
- R(running):表示進程正在運行。
- S(淺睡眠):例如,輸出一個字符只需1毫秒,但如果進程持續1秒(sleep(1)),剩余時間處于淺睡眠狀態,可以被kill命令終止。
- D(深度睡眠):通常與硬盤數據交換有關,不可被kill命令終止。
- Z(僵尸狀態):子進程在運行完后不會立即消失,而是先保留信息供父進程使用,信息保留在PCB中。
如果僵尸狀態一直存在,子進程的PCB就不會消失,可能會導致內存泄漏。
3. 小知識
進程退出后,內存泄漏的問題就不存在了(例如malloc,進程結束后,申請的內存會被系統回收)。常駐內存的軟件(例如Windows系統中的一些軟件,開機后一直運行)可能會導致系統卡頓。