1. 程式人生 > >windows下多程序通訊,基於共享記憶體環形佇列實現

windows下多程序通訊,基於共享記憶體環形佇列實現

  1 #include "stdafx.h"
  2 #include "InterProcessCommunication.h"
  3 #include <string>
  4 enum
  5 {
  6     STATE_EMPTY = 0,
  7     STATE_READ,
  8     STATE_WRITE
  9     
 10 };
 11 
 12 std::string InterProcessCommunication::PopString()
 13 {
 14     std::string buff;
 15     unsigned char
ch; 16 char* l=new char[256]; 17 char* str=l; 18 do{ 19 bufferPop(&ch); 20 *str++=(char)ch; 21 }while(ch!='\0'); 22 buff=std::string(l); 23 if(l!=NULL) 24 delete[] l; 25 l=NULL; 26 return buff; 27 } 28 29 void InterProcessCommunication::PushString(const
char* buff) 30 { 31 unsigned char* str=(unsigned char*)buff; 32 int len=strlen(buff); 33 //必須使用同步鎖,否則非同步寫入緩衝區會造成讀取順序混亂 34 WaitForSingleObject(pRwLock->hsynchronizedWrite,INFINITE); 35 for(int i=0;i<len;i++) 36 { 37 bufferPush(*str++); 38 } 39 bufferPush('
\0'); 40 ReleaseMutex(pRwLock->hsynchronizedWrite); 41 } 42 43 bool InterProcessCommunication::InitializeLock(const char* name) 44 { 45 std::string sharedMemoryName="shared_memory"+std::string(name); 46 std::string readHandleName="read"+std::string(name); 47 std::string writeHandleName="write"+std::string(name); 48 std::string eventLockName="eventLockName"+std::string(name); 49 std::string synchronizedWrite="synchronizedWrite"+std::string(name); 50 hMap = ::OpenFileMappingA( FILE_MAP_WRITE, false, sharedMemoryName.c_str()); 51 if ( hMap == NULL ) 52 { 53 int iErrCode = GetLastError(); 54 hMap=::CreateFileMappingA((HANDLE)-1,NULL,PAGE_READWRITE,0,sizeof(RWLock),sharedMemoryName.c_str()); 55 if (hMap == 0 ) 56 { 57 int iErrCode = GetLastError(); 58 return false ; 59 } 60 m_bCreator=true; 61 } 62 RWLock* _pRwLock = (RWLock*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); 63 HANDLE hRead=OpenMutexA(NULL,false,readHandleName.c_str()); 64 if(hRead==NULL) 65 { 66 hRead=CreateMutexA(NULL,false,readHandleName.c_str()); 67 if(hRead==NULL) return false; 68 } 69 HANDLE hWrite=OpenMutexA(NULL,false,writeHandleName.c_str()); 70 if(hWrite==NULL) 71 { 72 hWrite=CreateMutexA(NULL,false,writeHandleName.c_str()); 73 if(hWrite==NULL) return false; 74 } 75 hCondition=OpenEventA(EVENT_ALL_ACCESS ,NULL,eventLockName.c_str()); 76 if(hCondition==NULL) 77 { 78 hCondition=CreateEventA(NULL,false,false,eventLockName.c_str()); 79 if(hCondition==NULL) return false; 80 } 81 HANDLE hsynchronizedWrite=OpenMutexA(NULL,false,synchronizedWrite.c_str()); 82 if(hsynchronizedWrite==NULL) 83 { 84 hsynchronizedWrite=CreateMutexA(NULL,false,synchronizedWrite.c_str()); 85 if(hsynchronizedWrite==NULL) return false; 86 } 87 88 _pRwLock->hsynchronizedWrite=hsynchronizedWrite; 89 _pRwLock->hRead = hRead; 90 _pRwLock->hWrite = hWrite; 91 if(m_bCreator) 92 { 93 _pRwLock->count = 0; 94 } 95 _pRwLock->state = STATE_EMPTY; 96 pRwLock=_pRwLock; 97 98 return true; 99 } 100 101 void InterProcessCommunication::ReadLock() 102 { 103 assert(NULL != pRwLock); 104 WaitForSingleObject(pRwLock->hRead, INFINITE); 105 pRwLock->count ++; 106 if(1 == pRwLock->count){ 107 WaitForSingleObject(pRwLock->hWrite, INFINITE); 108 pRwLock->state = STATE_READ; 109 } 110 ReleaseMutex(pRwLock->hRead); 111 } 112 113 void InterProcessCommunication::WriteLock() 114 { 115 assert(NULL != pRwLock); 116 WaitForSingleObject(pRwLock->hWrite, INFINITE); 117 pRwLock->state = STATE_WRITE; 118 } 119 void InterProcessCommunication::UnLock() 120 { 121 assert(NULL != pRwLock); 122 if(STATE_READ == pRwLock->state){ 123 WaitForSingleObject(pRwLock->hRead, INFINITE); 124 125 pRwLock->count--; 126 if(0 == pRwLock->count){ 127 pRwLock->state = STATE_EMPTY; 128 ReleaseMutex(pRwLock->hWrite); 129 } 130 ReleaseMutex(pRwLock->hRead); 131 }else{ 132 pRwLock->state = STATE_EMPTY; 133 ReleaseMutex(pRwLock->hWrite); 134 } 135 return; 136 } 137 138 bool InterProcessCommunication::bufferPop(unsigned char* _buf) 139 { 140 label1: 141 if(pRwLock->buffer.head_pos==pRwLock->buffer.tail_pos) 142 { 143 WaitForSingleObject(hCondition, 500); 144 ResetEvent(hCondition); 145 goto label1; 146 } 147 else 148 { 149 *_buf=pRwLock->buffer.circle_buffer[pRwLock->buffer.head_pos]; 150 ReadLock(); 151 if(++pRwLock->buffer.head_pos>=BUFFER_MAX) 152 pRwLock->buffer.head_pos=0; 153 UnLock(); 154 return true; 155 } 156 } 157 void InterProcessCommunication::bufferPush(unsigned char _buf) 158 { 159 pRwLock->buffer.circle_buffer[pRwLock->buffer.tail_pos]=_buf; 160 WriteLock(); 161 if(++pRwLock->buffer.tail_pos>=BUFFER_MAX) 162 pRwLock->buffer.tail_pos=0; 163 //緩衝區資料滿後,尾指標與頭指標指向同一個地方,原資料被覆蓋 頭指標向前移動 164 if(pRwLock->buffer.tail_pos==pRwLock->buffer.head_pos) 165 if(++pRwLock->buffer.head_pos>=BUFFER_MAX) 166 pRwLock->buffer.head_pos=0; 167 UnLock(); 168 SetEvent(hCondition); 169 }