首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Windows 進程間通訊 (IPC) 實戰:共享記憶體高效資料交換

     編輯:VC 教學

共享記憶體:最快速的 IPC 機制

在 Windows 平台,記憶體對應檔案 是實現進程間高速資料共享的首選方案。核心優勢在於:

  • 零複製:進程直接映射同一塊物理記憶體頁框
  • 同步簡單:配合互斥體、事件、信號燈即可實現協調
  • 跨架構:32/64 位元進程皆可存取 (需注意指標大小)
  • 持久化選項:可關聯實體檔案實現斷電資料保留

核心 API 封裝實作

通用共享記憶體建立函數

HANDLE GetShare(char* &ShareP, int size, char* ShareName) {
    // 建立/開啟分頁檔對應物件
    // (HANDLE)-1 表示使用系統分頁檔,不關聯實體檔案
    HANDLE fh = CreateFileMapping(
        (HANDLE)-1,           // 使用系統分頁檔
        NULL,                 // 預設安全性
        PAGE_READWRITE,       // 讀寫權限
        0, size,              // 大小 (高/低 32 位元)
        ShareName             // 共享名稱 (全域命名空間)
    );
    
    // 映射視圖至進程位址空間
    ShareP = (char*)MapViewOfFile(fh, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    
    // 首次建立時初始化為零
    if (GetLastError() != ERROR_ALREADY_EXISTS) {
        ZeroMemory(ShareP, size);
    }
    return fh;
}

使用範例:128 位元組字元陣列共享

char* ShareP = NULL;

void test() {
    HANDLE fh = GetShare(ShareP, 128, "ShareForMyProg");
    for (int i = 0; i < 128; i++) {
        ShareP[i] = i;  // 寫入測試資料
    }
    CloseHandle(fh);  // 關閉控制代碼 (映射視圖保持有效直到 UnmapViewOfFile)
}

進階應用模式

1. 結構化資料共享

struct SharedData {
    volatile LONG sequence;      // 序號,用於讀寫同步
    DWORD timestamp;             // 時間戳
    char payload[1024];          // 實際資料
    CRITICAL_SECTION cs;         // 進程間關鍵區 (需初始化為共享)
};

// 初始化關鍵區 (僅建立者執行)
InitializeCriticalSectionAndSpinCount(&shared->cs, 0x80000000); // 設定互斥體屬性

2. 環形緩衝區 (生產者-消費者)

struct RingBuffer {
    volatile LONG head, tail;    // 原子操作索引
    char buffer[65536];          // 64KB 緩衝區
    // 無鎖寫入範例
    bool push(const char* data, int len) {
        LONG next = (head + 1) % sizeof(buffer);
        if (next == tail) return false; // 滿
        memcpy(buffer + head, data, len);
        InterlockedExchange(&head, next);
        return true;
    }
};

3. 跨進程同步物件

共享記憶體本身不提供同步,必須搭配:

  • Mutex:`CreateMutex(NULL, FALSE, "Global\\MySharedMutex")` - 互斥存取
  • Event:`CreateEvent(NULL, TRUE, FALSE, "Global\\DataReadyEvent")` - 資料就緒通知
  • Semaphore:控制併發存取數量

命名空間與安全性

  • Global\\ 前綴:跨 Session (服務 vs 互動使用者) 共享,需 `SeCreateGlobalPrivilege`
  • Local\\ 前綴:預設,僅限同一 Session 內
  • 安全性描述元:`CreateFileMapping` 第二參數傳 `SECURITY_ATTRIBUTES` 可限制存取權限 (如僅允許特定群組)

常見陷阱與最佳實務

陷阱解決方案
指標在進程間無效僅共享偏移量或索引,勿直接儲存/傳遞指標
32/64 位元指標大小不一使用固定大小型別 (int32_t, int64_t) 或相對偏移
未同步導致資料競爭必要時使用 Interlocked* 原子操作或關鍵區/互斥體
進程異常終止留下殘留物件啟動時檢查 `ERROR_ALREADY_EXISTS` 並驗證資料完整性
記憶體洩漏確保 `UnmapViewOfFile` 與 `CloseHandle` 配對呼叫

替代方案比較

  • Named Pipe:網路透明、訊息邊界、適合請求-回應模式
  • WM_COPYDATA:簡單、僅限 GUI 執行緒、資料複製開銷大
  • COM/ALPC:企業級、支援序列化、安全性豐富、複雜度高
  • Memory Mapped File:最高效能、最適合大量資料高頻交換

結語

共享記憶體透過 `CreateFileMapping`/`MapViewOfFile` 實現進程間零複製資料交換,是高效能 IPC 的核心技術。配合命名空間管理、安全性描述元、同步物件,可構建穩健的跨進程資料共享架構。開發時務必注意指標有效性、位元寬度相容、同步正確性與資源釋放,確保系統穩定與安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved