標籤:
共用記憶體主要是通過映射機制實現的。
Windows 下進程的地址空間在邏輯上是相互隔離的,但在物理上卻是重疊的。所謂的重疊是指同一塊記憶體地區可能被多個進程同時使用。當調用 CreateFileMapping 建立命名的記憶體對應檔對象時,Windows 即在實體記憶體申請一塊指定大小的記憶體地區,返迴文件映射對象的控制代碼 hMap。為了能夠訪問這塊記憶體地區必須調用 MapViewOfFile 函數,促使 Windows 將此記憶體空間映射到進程的地址空間中。當在其他進程訪問這塊記憶體地區時,則必須使用OpenFileMapping 函數取得物件控點 hMap,並調用 MapViewOfFile 函數得到此記憶體空間的一個映射。這樣一來,系統就把同一塊記憶體區域對應到了不同進程的地址空間中,從而達到共用記憶體的目的。
下面舉例說明如何將記憶體對應檔用於共用記憶體。
第一次運行這個例子時,它建立了共用記憶體,並寫入資料“This is common data!” 。只要建立共用記憶體的進程沒有關閉控制代碼hMap,以後啟動並執行程式就會讀出共用記憶體裡面的資料,並列印出來。這就是使用共用記憶體在處理序間通訊的過程。程式碼如下。
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 else29 { // 開啟成功,映射對象的一個視圖,得到指向共用記憶體的指標,顯示出裡面的資料30 pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);31 cout << "讀取共用記憶體資料:" << (char *)pBuffer << endl;32 }33 34 // 解除檔案對應,關閉記憶體對應檔物件控點35 ::UnmapViewOfFile(pBuffer);36 ::CloseHandle(hMap);37 system("pause"); // 注意,進程關閉後,所有控制代碼自動關閉,所以要在這裡暫停38 return 0;39 }
Windows共用記憶體樣本