UNIX/Linux:fork() + exec()
pid_t pid = fork();
if (pid == 0) { // 子進程
execl("/bin/ls", "ls", "-l", NULL); // 替換映像
perror("execl failed");
_exit(1);
} else if (pid > 0) { // 父進程
waitpid(pid, NULL, 0); // 等待子進程結束
} else {
perror("fork failed");
}
- fork():複製父進程地址空間 (Copy-on-Write 優化),返回子進程 PID=0,父進程 PID>0。
- exec() 族函數:載入新程序替換當前進程映像 (代碼段、數據段、堆棧),PID 不變。
- 優點:簡潔、靈活、父子關係天然、文件描述符繼承可控。
Windows:CreateProcess()
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL ok = CreateProcess(
L"C:\\Windows\\System32\\notepad.exe", // 應用程序名
NULL, // 命令行 (可為 NULL)
NULL, NULL, // 進程/線程安全屬性
FALSE, // 不繼承句柄
0, // 創建標誌
NULL, // 環境塊 (繼承父)
NULL, // 當前目錄 (繼承父)
&si, &pi // 輸出信息
);
if (ok) {
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
- 單一 API:一次性創建進程並加載可執行文件,無分離的 fork/exec。
- 參數豐富:指定安全屬性、繼承句柄、環境塊、當前目錄、啟動資訊 (窗口狀態、標準輸入輸出重定向) 等。
- 無原生 fork:Windows 進程地址空間獨立,不共享內存 (需顯式共享內存/映射文件)。
對比總結
| 特性 | UNIX (fork+exec) | Windows (CreateProcess) |
| API 設計 | 分離: 複製 + 替換 | 統一: 一次性創建加載 |
| 地址空間 | 子進程初始為父進程副本 (COW) | 全新獨立地址空間 |
| 資源繼承 | 文件描述符默認繼承 (可關閉) | 句柄可選繼承 (bInheritHandles) |
| 進程間通信 | 管道、Socket、共享內存、信號 | 管道、命名管道、共享內存、COM、RPC |
| 靈活性 | 極高 (fork 後可任意操作再 exec) | 參數化配置,相對固定 |
參考資源
UNIX 進程創建與 Windows CreateProcess 詳細對比