进程间通信--文件映射方式

1. 文件映射(Memory-Mapped Files)  
内存映射文件允许应用程序把文件映射到一个进程的虚拟地址空间,这样文件内的数据就可以用内存读写指令来访问。 
通过内存文件映射,应用程序不必执行文件I/O操作也无需对文件内容进行缓冲处理。内存文件映射的这种特性是非常适合于用来管理大尺寸文件的。  

2. 共享内存(Shared Memory)  
Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用INVALID_HANDLE_VALUE来代替文件句柄,就表示了对应的文件映射对象是由操作系统页面文件产生的,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。

     共享内存顾名思义是在内存中创建一个公共区域,供不同的进程间的数据共享。因为是直接对内存进行读写操作,效率非常高,所以共享内存特别适用于大批量的数据传输且实时性要求比较高的场合。

      具体操作步骤如下:

      1.进程A调用CreateFileMapping创建一个内存映射文件。

      2.进程A调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy往内存中拷贝数据。

      3.进程B调用CreateFileMapping打开进程A创建的内存映射文件。

      4.进程B调用MapViewOfFile获取到映射到文件的内存起始地址,调用memcpy从内存中读出数据。

      5.通信完后进程A,B分别调用UnmapViewOfFile,CloseHandle取消内存映射和关闭内存映射对象句柄。

参考代码如下:

 

  1 进程A:
  2 //
  3 //  FUNCTION: ShareMemoryCreate(LPCTSTR szMapName, DWORD dwSize)
  4 //
  5 //  PURPOSE:  create or open a map file
  6 //
  7 //  parameter:
  8 //            szMapName:name of the sharememory
  9 //            dwSize :  size 
 10 //  retun   :
 11 //            1:  create a mew file
 12 //            2:  open a file existed
 13 //
 14 //
 15 DWORD ShareMemoryCreate(LPCTSTR szMapName, DWORD dwSize)
 16 {
 17     DWORD dwRet = 1;
 18     HANDLE m_hShareMemory = NULL;    
 19 
 20     if(NULL == szMapName)
 21         return 0;
 22 
 23     if(NULL != m_hShareMemory)
 24         ShareMemoryClose(m_hShareMemory, m_pMapBuffer);
 25     //create the mapfile
 26     m_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, 
 27                                    PAGE_READWRITE, 0, dwSize, szMapName);
 28     if(!m_hShareMemory)
 29         return 0;
 30     //the mapfle has existed
 31     if(GetLastError() == ERROR_ALREADY_EXISTS)
 32     {
 33         dwRet = 2;
 34     }
 35     //gain the pointer of sharememory
 36     m_pMapBuffer = MapViewOfFile(m_hShareMemory, FILE_MAP_ALL_ACCESS,
 37                                   0, 0, dwSize);
 38     if(NULL == m_pMapBuffer)
 39     {
 40         CloseHandle(m_hShareMemory);
 41         return 0;
 42     }
 43     //create a mutuex, 用于读写同步
 44     TCHAR szMutexName[MAX_LOADSTRING];
 45     _tcscpy(szMutexName, szMapName);
 46     _tcscat(szMutexName, _T("_Mutex"));
 47     m_hAccessMutex = CreateMutex(NULL, FALSE, szMutexName);
 48     if(NULL == m_hAccessMutex)
 49     {
 50         ShareMemoryClose(m_hShareMemory, m_pMapBuffer);
 51         return 0;
 52     }
 53     return dwRet;
 54 }
 55 
 56 //
 57 //  FUNCTION: shareMemoryWrite(void* pBuf,DWORD dwSize,DWORD dwOffset)
 58 //
 59 //  PURPOSE:  write the data into sharememory  
 60 //
 61 //  parameter:
 62 //            pbuf:address of the sharememory
 63 //            dwSize :  size of the data
 64 //            dwoffset: offset with the start postion
 65 //  retun   :
 66 //            TRUE
 67 //            FALSE
 68 //
 69 //
 70 BOOL shareMemoryWrite(LPVOID m_pMapBuffer, TCHAR* pBuf,DWORD dwSize,DWORD dwOffset)
 71 {
 72     BOOL bRect;
 73 
 74     if(NULL == m_pMapBuffer)
 75         return FALSE;
 76     //收到信号时进行写操作
 77     if(WaitForSingleObject(m_hAccessMutex, INFINITE) == WAIT_OBJECT_0)
 78     {
 79         memcpy((TCHAR *)m_pMapBuffer+dwOffset, pBuf, dwSize);
 80         bRect = TRUE;
 81     }
 82     ReleaseMutex(m_hAccessMutex);
 83     return bRect;
 84 
 85 }
 86 
 87 //close the sharememory
 88 void ShareMemoryClose(HANDLE m_hShareMemory, LPVOID m_pMapBuffer)
 89 {
 90     if(m_hShareMemory)
 91     {
 92         UnmapViewOfFile(m_pMapBuffer);
 93         CloseHandle(m_hShareMemory);
 94         m_pMapBuffer   = NULL;
 95         m_hShareMemory = NULL;
 96     }
 97     if(m_hAccessMutex)
 98     {
 99         CloseHandle(m_hAccessMutex);
100         m_hAccessMutex = NULL;
101     }
102 }

 

 进程B
// 2 // FUNCTION: ShareMemoryCreate(LPCTSTR szMapName, DWORD dwSize) 3 // 4 // PURPOSE: create or open a map file 5 // 6 // parameter: 7 // szMapName:name of the sharememory 8 // dwSize : size 9 // retun : 10 // 1: create a mew file 11 // 2: open a file existed 12 // 13 // 14 DWORD ShareMemoryCreate(LPCTSTR szMapName, DWORD dwSize) 15 { 16 DWORD dwRet = 1; 17 18 if(NULL == szMapName) 19 return 0; 20 21 if(NULL != m_hShareMemory) 22 ShareMemoryClose(m_hShareMemory, m_pMapBuffer); 23 //create the mapfile 24 m_hShareMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, 25 PAGE_READWRITE, 0, SHARE_MEMORY_SIZE, TEXT("sharememoryfile")); 26 if(!m_hShareMemory) 27 return 0; 28 //the mapfle has existed 29 if(GetLastError() == ERROR_ALREADY_EXISTS) 30 { 31 dwRet = 2; 32 } 33 //gain the pointer of sharememory 34 m_pMapBuffer = MapViewOfFile(m_hShareMemory, FILE_MAP_ALL_ACCESS,0, 0, SHARE_MEMORY_SIZE); 35 36 TCHAR szMutexName[MAX_LOADSTRING]; 37 _tcscpy(szMutexName, szMapName); 38 _tcscat(szMutexName, _T("_Mutex")); 39 m_hAccessMutex = CreateMutex(NULL, FALSE, szMutexName); 40 if(NULL == m_hAccessMutex) 41 { 42 ShareMemoryClose(m_hShareMemory, m_pMapBuffer); 43 return 0; 44 } 45 return dwRet; 46 } 47 // 48 // FUNCTION: shareMemoryRead(void* pBuf,DWORD dwSize,DWORD dwOffset = 0) 49 // 50 // PURPOSE: read the data from the sharememory 51 // 52 // parameter: 53 // pbuf:address of the sharememory 54 // dwSize : size of the data 55 // dwoffset: offset with the start postion 56 // retun : 57 // TRUE 58 // FALSE 59 // 60 // 61 /**/ 62 BOOL shareMemoryRead(LPVOID m_pMapBuffer, TCHAR* pBuf,DWORD dwSize, DWORD dwOffset) 63 { 64 BOOL bRet; 65 if(NULL == m_pMapBuffer) 66 return FALSE; 67 if(WaitForSingleObject(m_hAccessMutex, INFINITE) == WAIT_OBJECT_0) 68 { 69 memcpy(pBuf, (TCHAR *)m_pMapBuffer+dwOffset, dwSize); 70 bRet = TRUE; 71 } 72 ReleaseMutex(m_hAccessMutex); 73 74 return bRet; 75 } 76 //close the sharememory 77 void ShareMemoryClose(HANDLE m_hShareMemory, LPVOID m_pMapBuffer) 78 { 79 if(m_hShareMemory) 80 { 81 UnmapViewOfFile(m_pMapBuffer); 82 CloseHandle(m_hShareMemory); 83 m_pMapBuffer = NULL; 84 m_hShareMemory = NULL; 85 } 86 if(m_hAccessMutex) 87 { 88 CloseHandle(m_hAccessMutex); 89 m_hAccessMutex = NULL; 90 } 91 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。