一、進程概念
在 Linux 系統中,??進程(Process)?? 是程序執行的動態實例,是操作系統進行資源分配和調度的基本單位。
??1. 程序 vs 進程??
??程序(Program)??:是靜態的代碼集合(如二進制可執行文件 /bin/ls),存儲在磁盤上,不占用系統資源(如 CPU、內存)。
??進程(Process)??:是程序被加載到內存后??動態運行??的狀態,是操作系統管理的“活”的實體。同一程序可被多次執行,生成多個獨立的進程(如同時打開多個 bash 終端)。
二、進程的核心特性
??1. 動態性??:進程是程序執行的動態過程,有生命周期(創建→運行→終止)。
??2. 并發性??:多個進程可在同一時間段內交替運行(宏觀并行,微觀串行),由操作系統調度實現。
??3. 獨立性??:每個進程擁有獨立的資源空間(如內存、文件句柄),通過內核隔離,一個進程崩潰不影響其他進程(除非涉及共享資源)、一個進程也無法直接訪問其他進程內存的資源。
??4. 異步性??:進程的執行順序由操作系統調度決定,具有不確定性(受優先級、資源競爭等因素影響)。
三、進程狀態與切換
Linux 進程的狀態反映了其當前的活動情況,常見狀態包括:
狀態轉換示例??:
- 新進程通過 fork() 創建 → 進入 R(就緒)或直接運行(若 CPU 空閑)。
- 進程因 I/O 請求進入 S(可中斷睡眠),I/O 完成后被喚醒回 R。
- 進程收到 SIGKILL 信號 → 強制終止,釋放資源(避免變為僵尸)。
- 父進程未調用 wait() 回收子進程 → 子進程終止后變為 Z(僵尸)。
四、進程的描述:進程控制塊(PCB)??
Linux 內核通過 ??task_struct 結構體??(進程控制塊,PCB)描述進程的所有信息,存儲于內核內存中。關鍵字段包括:
??1. 標識信息??:進程 ID(PID,進程的唯一標識)、父進程 ID(PPID)、用戶 ID(UID)、組 ID(GID)。
2. ??狀態信息??:當前狀態(如 R/S/Z)、退出狀態碼(終止原因)。
??3. 資源信息??:虛擬內存映射(mm_struct)、打開的文件描述符表(files_struct)、信號處理方式(signal_struct)。
??4. 調度信息??:優先級(nice 值)、CPU 占用時間(utime/stime)、調度策略(如 CFS 公平調度)。
??5. 上下文信息??:寄存器值(如程序計數器 PC、棧指針 SP)、浮點運算狀態(用于進程切換時保存現場)。
??五、進程的創建與終止??
??1. 進程創建??
Linux 中進程通過 fork() 系統調用創建,遵循“??寫時復制(Copy-On-Write)??”原則:
父進程調用 fork() 后,內核復制父進程的 PCB 和內存頁表(初始時共享物理內存),生成子進程。
子進程從 fork() 的返回值開始往后執行(fork()系統調用,在父進程的代碼是返回子進程 PID,在子進程的代碼中則是返回 0)。
實際內存復制僅在子進程修改內存時發生(提高效率)。
明明是父進程調用了fork,為什么fork在子進程中也返回了一直值?而且值是0,和父進程的不一樣?
解釋: 從內核源碼(如 Linux 的 fork() 實現)來看,fork() 的返回值是通過??修改調用者的寄存器狀態??實現的:
-
當父進程調用 fork() 時,內核會復制父進程的上下文到子進程,并分別設置兩個進程的“返回寄存器”:
-
父進程的返回寄存器被設置為子進程的 PID(正數)。子進程的返回寄存器被設置為 0(表示無錯誤且是子進程)。因此,父進程和子進程在 fork() 后從同一條指令繼續執行,但由于寄存器中的返回值不同,它們的后續邏輯會分道揚鑣。