Windows 提供多種 IPC 機制(Socket、Pipe、Mailslot、RPC、COM),但共享記憶體 (Shared Memory) 是延遲最低、吞吐最高的核心方式。底層透過 File Mapping API 實現:將實體記憶體區域映射到多個進程的虛擬位址空間,實現零拷貝資料交換。
// 1. 建立/開啟檔案映射物件
HANDLE hMap = CreateFileMapping(
INVALID_HANDLE_VALUE, // 無實體檔案,使用分頁檔
&sa, // SECURITY_ATTRIBUTES,bInheritHandle=TRUE 可讓子進程繼承
PAGE_READWRITE, // 頁面保護屬性
0, // dwMaximumSizeHigh (64-bit 大小高 32 位)
size, // dwMaximumSizeLow (最大 4GB)
L"Global\\MySharedMem" // 命名物件,跨進程開啟
);
// 2. 映射視圖到進程虛擬位址
LPVOID pView = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
// 3. 讀寫資料(需自行同步,如 Mutex/Event)
// ...
// 4. 清理
UnmapViewOfFile(pView);
CloseHandle(hMap);
CreateFileMapping 指定名稱,另一進程用 OpenFileMapping 開啟。簡單但需協調名稱衝突。DuplicateHandle 複製 Handle,透過命令列、環境變數、共用記憶體或 IPC 訊息傳遞給子進程。優雅且安全。CreateFileMapping 時 SECURITY_ATTRIBUTES.bInheritHandle=TRUE,配合 CreateProcess(bInheritHandles=TRUE),核心自動複製 Handle 到子進程(Handle 值相同),無需額外傳遞。MapViewOfFile 可指定 dwFileOffsetHigh/Low 與 dwNumberOfBytesToMap,將 >4GB 檔案分段映射到 32 位址空間(或 64 位進程 2GB 使用者空間限制)。
// 父進程
SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE};
HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, 4096, NULL);
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
CreateProcess(L"Child.exe", L"Child.exe 1234", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
// Handle 1234 自動繼承到子進程,子進程直接用此值 MapViewOfFile
CreateProcess 的 lpCommandLine 必須指向可寫緩衝區(不可用字串常值),否則會崩潰。STARTUPINFO 建議用 GetStartupInfo 取得預設值再修改,避免結構未初始化。CloseHandle 釋放引用計數,否則核心物件洩漏。Mutex、Event、Semaphore 或 Interlocked* 原子操作。