共享內存主要是經過映射機制實現的。
Windows 下進程的地址空間在邏輯上是相互隔離的,但在物理上倒是重疊的。所謂的重疊是指同一塊內存區域可能被多個進程同時使用。當調用 CreateFileMapping 建立命名的內存映射文件對象時,Windows 即在物理內存申請一塊指定大小的內存區域,返回文件映射對象的句柄 hMap。爲了可以訪問這塊內存區域必須調用 MapViewOfFile 函數,促使 Windows 將此內存空間映射到進程的地址空間中。當在其餘進程訪問這塊內存區域時,則必須使用OpenFileMapping 函數取得對象句柄 hMap,並調用 MapViewOfFile 函數獲得此內存空間的一個映射。這樣一來,系統就把同一塊內存區域映射到了不一樣進程的地址空間中,從而達到共享內存的目的。ios
下面舉例說明如何將內存映射文件用於共享內存。
第一次運行這個例子時,它建立了共享內存,並寫入數據「This is common data!」 。只要建立共享內存的進程沒有關閉句柄hMap,之後運行的程序就會讀出共享內存裏面的數據,並打印出來。這就是使用共享內存在進程間通訊的過程。程序代碼以下。windows
1 #include <windows.h> 2 #include <iostream> 3 #include <string> 4 #include <cstring> 5 using namespace std; 6 7 int main() 8 { 9 string strMapName("ShareMemory"); // 內存映射對象名稱 10 string strComData("This is common data!"); // 共享內存中的數據 11 LPVOID pBuffer; // 共享內存指針 12 13 // 首先試圖打開一個命名的內存映射文件對象 14 HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, strMapName.c_str()); 15 if (NULL == hMap) 16 { // 打開失敗,建立之 17 hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, 18 NULL, 19 PAGE_READWRITE, 20 0, 21 strComData.length()+1, 22 strMapName.c_str()); 23 // 映射對象的一個視圖,獲得指向共享內存的指針,設置裏面的數據 24 pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 25 strcpy((char*)pBuffer, strComData.c_str()); 26 cout << "寫入共享內存數據:" << (char *)pBuffer << endl; 27 } 28 else 29 { // 打開成功,映射對象的一個視圖,獲得指向共享內存的指針,顯示出裏面的數據 30 pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 31 cout << "讀取共享內存數據:" << (char *)pBuffer << endl; 32 } 33 34 getchar(); // 注意,進程關閉後,全部句柄自動關閉,因此要在這裏暫停 35 36 // 解除文件映射,關閉內存映射文件對象句柄 37 ::UnmapViewOfFile(pBuffer); 38 ::CloseHandle(hMap); 39 system("pause"); 40 return 0; 41 }
連續兩次運行這個程序,它們的輸出結果以下所示:app