承接上篇 fork() 創建進程,本文深入講解 vfork() 的獨特機制:地址空間共享、子進程優先調度、修改父進程數據可見性,並通過對比實驗驗證核心差異。
| 特性 | fork() | vfork() |
|---|---|---|
| 調用返回 | 一次調用,兩次返回 | 一次調用,兩次返回 |
| 資源複製 | 完全複製父進程資源(寫時複製 COW) | 不複製,子進程共享父進程地址空間 |
| 數據隔離 | 子父進程數據互不影響 | 子進程修改直接影響父進程 |
| 調度順序 | 不確定,由調度器決定 | 保證子進程先運行,直到 exec 或 exit |
| 死鎖風險 | 無 | 子進程依賴父進程行為時極易死鎖 |
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
int globVar = 5;
int main(void) {
pid_t pid;
int var = 1, i;
printf("fork vs vfork demonstration\n");
// pid = fork(); // 實驗1:取消註釋測試 fork
pid = vfork(); // 實驗2:取消註釋測試 vfork
switch(pid) {
case 0: // 子進程
i = 3;
while(i-- > 0) {
printf("Child process is running\n");
globVar++; var++;
sleep(1);
}
printf("Child's globVar = %d, var = %d\n", globVar, var);
_exit(0); // vfork 必須用 _exit,避免刷新父進程緩衝區
case -1:
perror("Process creation failed");
exit(1);
default: // 父進程
i = 5;
while(i-- > 0) {
printf("Parent process is running\n");
globVar++; var++;
sleep(1);
}
printf("Parent's globVar = %d, var = %d\n", globVar, var);
exit(0);
}
}

分析:
globVar=8, var=4globVar=10, var=6
分析:
_exit 後父進程繼續遞增 5 次globVar=13, var=9(5+3+5)ps 查看父進程狀態為 S(可中斷睡眠/阻塞)_exit() 而非 exit():exit() 會刷新 stdio 緩衝區,破壞父進程緩衝區狀態exec() 的場景:現代 Linux fork() 已優化(COW),性能差異微乎其微,vfork() 除非極度敏感場景不推薦常規使用posix_spawn() 或帶 clone() 參數的 fork()S:可中斷睡眠(等待事件)D:不可中斷睡眠(通常為 I/O)ps -eo pid,ppid,stat,cmd 觀察父進程阻塞狀態本文出自 “_Liang_Happy_Life__Dream” 博客,轉載請保留出處:原文鏈接