zoukankan      html  css  js  c++  java
  • 进程间通信--文件映射方式

    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 }
  • 相关阅读:
    C字符串处理函数
    C语言字符串函数大全
    那些闪亮的日子
    牛客网在线编程:幸运数
    牛客网在线编程:水仙花数
    [LeetCode]617.Merge Two Binary Trees
    [LeetCode]657.Judge Route Circle
    [LeetCode]141. Linked List Cycle
    五大算法:分治,贪心,动态规划,回溯,分支界定
    [LeetCode]387.First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/philospy/p/4403300.html
Copyright © 2011-2022 走看看