进程间通信-共享内存

把之前代码整理下,封装了一个用于共享内存的类。

头文件:CShareMem.h

 1 /* @CShareMem类用于内存映射文件,在进程间传输帧数据 */
 2 enum eDATATYPE { NONE_TYPE, FRAME_TYPE, STATUS_TYPE, INFO_TYPE, CMD_TYPE };
 3 class CShareMem
 4 {
 5 public:
 6     enum EM_EVENS { EV_NONE, EV_READ_THIS, EV_WRITE_THIS, EV_READ_OTHER, EV_WRITE_OTHER, EV_TIMEOUT };
 7 public: 
 8     struct SM_MEMFLAG
 9     {
10         enum eMemFlag{ ACT_NONE, ACT_READ, ACT_WRITE } eLastAction;
11         DWORD dwProcessId; 
12         eDATATYPE eDataType;
13         UDPFrameData m_DataHead;
14         char m_DataBuff[BUFFER_SIZE];        // Text from client to server
15     }; 
16     class SM_MEMPTR
17     {
18     public: 
19         ~SM_MEMPTR();
20         SM_MEMFLAG* m_pMemFlag;
21     private:
22         friend class CShareMem;
23         SM_MEMPTR(CShareMem&, SM_MEMFLAG*, SM_MEMFLAG::eMemFlag);
24         CShareMem& m_ShareMemory; 
25     };
26     //
27     CShareMem(CONST TCHAR* lpName = RZT_FRAME_RECV);
28     ~CShareMem();
29     /* @ 使用这个函数获得内存映射的指针,可用于直接存放或读取数据
30        @ { std::auto_ptr<SM_MEMPTR> ptr = GetMemptr(SM_MEMFLAG::ACT_READ); use ptr .. }
31     */
32     std::auto_ptr<SM_MEMPTR> GetMemptr(SM_MEMFLAG::eMemFlag eFlag)
33     {
34         return auto_ptr<SM_MEMPTR>(new SM_MEMPTR(*this, m_pMemFlag,eFlag));
35     }  
36     EM_EVENS WaitEvent(DWORD dwTimeOut);
37     void WaitEvent(EM_EVENS eEvent);
38     bool Read(UDPFrameData* pDataHead, char* pData, eDATATYPE* type = nullptr);
39     bool Write(UDPFrameData* pDataHead,const char* pData, eDATATYPE type = FRAME_TYPE);
40 private:
41     DWORD m_dwProcessId;
42     HANDLE m_hMemory;
43     HANDLE m_hMutex;
44     HANDLE m_hEvent;
45     SM_MEMFLAG* m_pMemFlag;
46     char * m_DataBuff;
47     UDPFrameData * m_DataHead;
48 };

实现文件:CShareMem.cpp

  1 CShareMem::CShareMem(CONST TCHAR* lpName):m_hMemory(NULL), m_hMutex(NULL), m_hEvent(NULL)
  2 { 
  3     m_dwProcessId = GetCurrentProcessId(); 
  4     if (!lpName)
  5     {
  6         lpName = _T("SHARE.MEMORY");
  7     }
  8     m_hMemory = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUFFER_SIZE, lpName);
  9     if (::GetLastError() == ERROR_ALREADY_EXISTS)
 10     {
 11         m_hMemory = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, lpName);
 12     }
 13     if (m_hMemory == NULL)
 14     {
 15         ostringstream os;
 16         os << "CreateFileMapping: %s Failed!" << lpName << endl;
 17         LOGFMTE(os.rdbuf()->str().c_str());
 18     }
 19     m_pMemFlag = (SM_MEMFLAG*)::MapViewOfFile(m_hMemory, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(SM_MEMFLAG));
 20     m_DataBuff = m_pMemFlag->m_DataBuff;
 21     m_DataHead = &m_pMemFlag->m_DataHead;
 22     {
 23         TCHAR tcTempName[96] = _T("");
 24         _stprintf_s(tcTempName, _T("%s.Mutex"), lpName);
 25         m_hMutex = ::CreateMutex(NULL, FALSE, tcTempName);
 26         if (m_hMutex == NULL)
 27         {
 28             LOGFMTE(_T("CreateMutex %s Failed"), tcTempName);
 29         }
 30         _stprintf_s(tcTempName, _T("%s.Event"), lpName);
 31         m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, tcTempName);
 32         if (m_hEvent == NULL)
 33         {
 34             LOGFMTE(_T("CreateEvent %s Failed"), tcTempName);
 35         }
 36     }
 37 }
 38 CShareMem::~CShareMem(void)
 39 {
 40     ::UnmapViewOfFile(m_pMemFlag);
 41     ::CloseHandle(m_hMemory);
 42     ::CloseHandle(m_hMutex);
 43     ::CloseHandle(m_hEvent);
 44 }
 45 #define SM_LOCK ::WaitForSingleObject(m_hMutex, INFINITE)
 46 #define SM_UNLOCK ::ReleaseMutex(m_hMutex)
 47 #define SM_SIGNAR ::SetEvent(m_hEvent)
 48 #define SM_RESETEVEN ::ResetEvent(m_hEvent)
 49 CShareMem::SM_MEMPTR::SM_MEMPTR(CShareMem& ShareMemory, SM_MEMFLAG* pMemFlag, SM_MEMFLAG::eMemFlag eFlag)
 50     :m_ShareMemory(ShareMemory)
 51     ,m_pMemFlag(pMemFlag)
 52 { 
 53     ::WaitForSingleObject(m_ShareMemory.m_hMutex, INFINITE);  
 54     m_pMemFlag->dwProcessId = m_ShareMemory.m_dwProcessId;
 55     m_pMemFlag->eLastAction = eFlag;
 56 }
 57 
 58 CShareMem::SM_MEMPTR::~SM_MEMPTR()
 59 { 
 60     ::ReleaseMutex(m_ShareMemory.m_hMutex);
 61     ::SetEvent(m_ShareMemory.m_hEvent);
 62 }
 63 CShareMem::EM_EVENS CShareMem::WaitEvent(DWORD dwTimeOut)
 64 {
 65     DWORD dwState = WaitForSingleObject(m_hEvent, dwTimeOut);
 66     EM_EVENS rtEvent = EV_NONE;
 67     SM_LOCK;
 68     switch (dwState)
 69     {
 70     case WAIT_OBJECT_0:
 71         switch (m_pMemFlag->eLastAction)
 72         {
 73         case SM_MEMFLAG::ACT_READ:
 74             rtEvent = m_pMemFlag->dwProcessId == m_dwProcessId ? EV_READ_THIS : EV_READ_OTHER;
 75             break;
 76         case SM_MEMFLAG::ACT_WRITE:
 77             rtEvent = m_pMemFlag->dwProcessId == m_dwProcessId ? EV_WRITE_THIS : EV_WRITE_OTHER; 
 78             break;
 79         } 
 80         break;
 81     case WAIT_TIMEOUT:
 82         rtEvent = EV_TIMEOUT;
 83         break;
 84     default:
 85         break;
 86     }
 87     SM_UNLOCK;
 88     SM_RESETEVEN;
 89     return rtEvent;
 90 }
 91 
 92 void CShareMem::WaitEvent(EM_EVENS eEvent)
 93 { 
 94     while (WaitEvent(INFINITE) != eEvent);
 95 }
 96 bool CShareMem::Write(UDPFrameData* pDataHead, const char* pData, eDATATYPE type)
 97 {
 98     for (;;)
 99     {
100         if (m_pMemFlag == NULL)
101         {
102             return false;
103         }
104         if (m_pMemFlag->eLastAction == SM_MEMFLAG::ACT_WRITE)
105         {
106             Sleep(1);
107         }
108         else
109         {
110             break;
111         }
112     }
113 
114     SM_LOCK; 
115     memcpy_s(m_DataHead, HEADER_SIZE, pDataHead, HEADER_SIZE);
116     memcpy_s(m_DataBuff, pDataHead->m_nFrameSize, pData, pDataHead->m_nFrameSize); 
117     m_pMemFlag->eDataType = type;
118     m_pMemFlag->dwProcessId = m_dwProcessId;
119     m_pMemFlag->eLastAction = SM_MEMFLAG::ACT_WRITE;
120     SM_SIGNAR;
121     SM_UNLOCK;
122     return true;
123 }
124 bool CShareMem::Read(UDPFrameData* pDataHead, char* pData, eDATATYPE* type)
125 {
126     for(;;)
127     {
128         if (m_pMemFlag == NULL)
129         {
130             return false;
131         }
132         if (m_pMemFlag->eLastAction != SM_MEMFLAG::ACT_WRITE)//
133         {
134             Sleep(1);
135         }
136         else
137         {
138             break;
139         }
140     }
141     SM_LOCK; 
142     memcpy_s(pDataHead, HEADER_SIZE, m_DataHead, HEADER_SIZE);
143     memcpy_s(pData, pDataHead->m_nFrameSize, m_DataBuff, pDataHead->m_nFrameSize);
144     if (type)
145     {
146         *type = m_pMemFlag->eDataType;
147     }
148     m_pMemFlag->dwProcessId = m_dwProcessId;
149     m_pMemFlag->eLastAction = SM_MEMFLAG::ACT_READ;
150     SM_SIGNAR; 
151     SM_UNLOCK;
152     return true;
153 }
原文地址:https://www.cnblogs.com/xuyouzhu/p/8757601.html