進程三態(運行、就緒、阻塞)是 OS 課程核心考點。本文結合 GCC 編譯器處理 C 文件 的具體生命周期,逐幀拆解狀態流轉,並補充四態模型(增加睡眠態)的工程意義。
| 階段 | 進程動作 | 狀態 | 觸發轉換的事件 |
|---|---|---|---|
| 1. Shell fork/exec | 創建 gcc 進程,載入代碼段 | 就緒 → 運行 | 調度器分派 CPU |
| 2. 預處理 (cpp) | 讀取 .h/.c 文件,展開宏 | 運行 → 阻塞 | 發起磁盤 I/O 讀取頭文件 |
| 3. 磁盤完成中斷 | 數據已在內存緩衝區 | 阻塞 → 就緒 | I/O 完成中斷,內核喚醒進程 |
| 4. 等待 CPU | 在就緒隊列排隊 | 就緒 | 更高優先級進程搶佔、時間片用盡 |
| 5. 編譯 (cc1) | 語法分析、優化、生成汇编 | 就緒 → 運行 | 調度器再次分派 |
| 6. 寫入 .s 文件 | 調用 write() 系統調用 | 運行 → 阻塞 | 磁盤寫入 I/O |
| 7. 汇編 (as) | 生成 .o 目標文件 | 阻塞 → 就緒 → 運行 | 同 3→4→5 |
| 8. 鏈接 (ld) | 解析符號、合併段、生成可執行文件 | 運行(長時間計算密集) | 若內存不足觸發換頁 → 阻塞 |
| 9. 退出 | exit() 釋放資源 | 運行 → 終止 | 進程正常結束 |
+-----------------+
| 新建/就緒 |
+--------+--------+
| 調度分派
v
+--------+--------+ I/O 請求/等待事件 +--------+--------+
| 運行態 | ----------------------------> | 阻塞態 |
+--------+--------+ +--------+--------+
^ |
| 時間片用盡/搶佔 | 事件發生/中斷喚醒
| v
+--------+--------+ <------------------------------ +--------+--------+
| 就緒態 | 就緒喚醒 | (同阻塞) |
+-----------------+ +-----------------+
Linux 內核將「可中斷等待」細分為 TASK_INTERRUPTIBLE (睡眠) 與 TASK_UNINTERRUPTIBLE (深度阻塞):
sleep(1)、pthread_cond_wait)。工程上:ps -eo stat 中 S=睡眠、D=深度阻塞、R=運行/就緒。排查卡頓時關注 D 狀態進程堆棧。
掌握「誰發起、經過哪個隊列、由誰喚醒」三要素,即可應對所有狀態轉換題目。