CircularBuf.h
1 #ifndef CIRCULAR_BUF_H 2 #define CIRCULAR_BUF_H 3 4 #include <Windows.h> 5 6 #define MULTI_BUF_SIZE 10 7 #define MULTI_MIN_BUF_DATA_SIZE 5 8 9 class CCircularBuf 10 { 11 public: 12 CCircularBuf(void); 13 ~CCircularBuf(void); 14 15 //创建缓冲区 16 long createBuf(const long size, const HANDLE writeEvent, const HANDLE readEvent); 17 18 //释放缓冲区 19 long releaseBuf(void); 20 21 //读 22 long readBuf(char *pBuf, const long bytes); 23 24 //写 25 long writeBuf(const char *pBuf, const long bytes); 26 27 private: 28 //获取写指针 29 long getWritePos(const long size, long *pos1, long *pos2, 30 long *len1, long *len2); 31 32 //获取读指针 33 long getReadPos(const long size, long *pos1, long *pos2, 34 long *len1, long *len2); 35 36 //修改写指针 37 long setWritePos(const long pos); 38 39 //修改读指针 40 long setReadPos(const long pos); 41 42 43 private: 44 char *pCirBuf; 45 long lBufSize; 46 long lMaxRWBufSize; 47 48 long lWritePos; 49 long lReadPos; 50 51 HANDLE hWriteEvent; 52 HANDLE hReadEvent; 53 54 CRITICAL_SECTION csCirBuf; 55 }; 56 57 #endif
CircularBuf.cpp
1 #include "stdafx.h" 2 #include "CircularBuf.h" 3 4 CCircularBuf::CCircularBuf(void) 5 { 6 pCirBuf = NULL; 7 lBufSize = 0; 8 lMaxRWBufSize = 0; 9 10 hWriteEvent = 0; 11 hReadEvent = 0; 12 13 lWritePos = 0; 14 lReadPos = 0; 15 } 16 17 CCircularBuf::~CCircularBuf(void) 18 { 19 } 20 21 //创建缓冲区 22 long CCircularBuf::createBuf(long size, const HANDLE writeEvent, const HANDLE readEvent) 23 { 24 if (!size || !writeEvent || !readEvent) 25 { 26 return -1; 27 } 28 29 pCirBuf = new char [size * MULTI_BUF_SIZE]; 30 if (!pCirBuf) 31 { 32 return -1; 33 } 34 35 memset(pCirBuf, 0, size * MULTI_BUF_SIZE); 36 lMaxRWBufSize = size; 37 lBufSize = size * MULTI_BUF_SIZE; 38 39 hWriteEvent = writeEvent; 40 hReadEvent = readEvent; 41 42 lWritePos = 0; 43 lReadPos = 0; 44 45 InitializeCriticalSection(&csCirBuf); 46 return 0; 47 } 48 49 //释放缓冲区 50 long CCircularBuf::releaseBuf(void) 51 { 52 if (!lBufSize) 53 { 54 return -1; 55 } 56 57 EnterCriticalSection(&csCirBuf); 58 if (pCirBuf) 59 { 60 delete []pCirBuf; 61 pCirBuf = NULL; 62 } 63 64 lMaxRWBufSize = 0; 65 lBufSize = 0; 66 67 hWriteEvent = 0; 68 hReadEvent = 0; 69 70 lWritePos = 0; 71 lReadPos = 0; 72 LeaveCriticalSection(&csCirBuf); 73 DeleteCriticalSection(&csCirBuf); 74 75 return 0; 76 } 77 78 //读 79 long CCircularBuf::readBuf(char *pBuf, const long bytes) 80 { 81 long pos1 = 0; 82 long pos2 = 0; 83 long len1 = 0; 84 long len2 = 0; 85 long realBytes = 0; 86 87 if (bytes > lMaxRWBufSize || !pBuf) 88 { 89 return -1; 90 } 91 92 EnterCriticalSection(&csCirBuf); 93 if (getReadPos(bytes, &pos1, &pos2, &len1, &len2)) 94 { 95 LeaveCriticalSection(&csCirBuf); 96 return -1; 97 } 98 99 if (pos2) 100 { 101 memcpy(pBuf, &pCirBuf[pos1], len1); 102 realBytes = len1; 103 setReadPos(pos1 + len1); 104 } 105 else 106 { 107 memcpy(pBuf, &pCirBuf[pos1], len1); 108 memcpy(&pBuf[len1], &pCirBuf, len2); 109 realBytes = len1 + len2; 110 setReadPos(len2); 111 } 112 LeaveCriticalSection(&csCirBuf); 113 114 return realBytes; 115 } 116 117 //写 118 long CCircularBuf::writeBuf(const char *pBuf, const long bytes) 119 { 120 long pos1 = 0; 121 long pos2 = 0; 122 long len1 = 0; 123 long len2 = 0; 124 long writeBytes = 0; 125 126 if (bytes > lMaxRWBufSize || !pBuf) 127 { 128 return -1; 129 } 130 131 EnterCriticalSection(&csCirBuf); 132 if (getWritePos(bytes, &pos1, &pos2, &len1, &len2)) 133 { 134 LeaveCriticalSection(&csCirBuf); 135 return -1; 136 } 137 138 if (pos2) 139 { 140 memcpy(&pCirBuf[pos1], pBuf, len1); 141 writeBytes = len1; 142 setWritePos(pos1 + len1); 143 } 144 else 145 { 146 memcpy(&pCirBuf[pos1], pBuf, len1); 147 memcpy(&pCirBuf, &pBuf[len1], len2); 148 writeBytes = len1 + len2; 149 setWritePos(len2); 150 } 151 LeaveCriticalSection(&csCirBuf); 152 153 return writeBytes; 154 } 155 156 //获取写指针 157 long CCircularBuf::getWritePos(const long size, long *pos1, long *pos2, 158 long *len1, long *len2) 159 { 160 if (!pos1 || !pos2 || *len1 || *len2) 161 { 162 return -1; 163 } 164 165 *pos1 = lWritePos; 166 if (lWritePos < lReadPos)//写指针在读指针左,不可能循环 167 { 168 *pos2 = lBufSize; 169 *len2 = 0; 170 if (lWritePos + size > lReadPos) 171 { 172 *len1 = lReadPos - lWritePos; 173 } 174 else 175 { 176 *len1 = size; 177 } 178 } 179 else//写指针在读指针右,可能循环 180 { 181 if (lWritePos + size > lBufSize) 182 { 183 *len1 = lBufSize - lWritePos; 184 *pos2 = 0; 185 *len2 = size + lWritePos - lBufSize; 186 if (*len2 > lReadPos) 187 { 188 *len2 = lReadPos; 189 } 190 } 191 else 192 { 193 *len1 = size; 194 *pos2 = lBufSize; 195 *len2 = 0; 196 } 197 } 198 199 return 0; 200 } 201 202 203 //获取读指针 204 long CCircularBuf::getReadPos(const long size, long *pos1, long *pos2, 205 long *len1, long *len2) 206 { 207 if (!pos1 || !pos2 || *len1 || *len2) 208 { 209 return -1; 210 } 211 212 *pos1 = lReadPos; 213 if (lReadPos <= lWritePos)//读指针在写指针左,不可能循环 214 { 215 *pos2 = lBufSize; 216 *len2 = 0; 217 if (lReadPos + size > lWritePos) 218 { 219 *len1 = lWritePos - lReadPos; 220 } 221 else 222 { 223 *len1 = size; 224 } 225 } 226 else//读指针在写指针右,可能循环 227 { 228 if (lReadPos + size > lBufSize) 229 { 230 *len1 = lBufSize - lReadPos; 231 *pos2 = 0; 232 *len2 = size + lReadPos - lBufSize; 233 if (*len2 > lWritePos) 234 { 235 *len2 = lWritePos; 236 } 237 } 238 else 239 { 240 *len1 = size; 241 *pos2 = lBufSize; 242 *len2 = 0; 243 } 244 } 245 246 return 0; 247 } 248 249 250 //修改写指针 251 long CCircularBuf::setWritePos(const long pos) 252 { 253 if (pos >= lBufSize) 254 { 255 lWritePos = pos - lBufSize; 256 } 257 else 258 { 259 lWritePos = pos; 260 } 261 262 if (lReadPos > lWritePos) 263 { 264 if (lBufSize - lReadPos + lWritePos > MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) 265 { 266 SetEvent(hReadEvent); 267 } 268 } 269 else 270 { 271 if (lWritePos - lReadPos > MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) 272 { 273 SetEvent(hReadEvent); 274 } 275 } 276 277 return 0; 278 } 279 280 //修改读指针 281 long CCircularBuf::setReadPos(const long pos) 282 { 283 if (pos >= lBufSize) 284 { 285 lReadPos = pos - lBufSize; 286 } 287 else 288 { 289 lReadPos = pos; 290 } 291 292 if (lReadPos > lWritePos) 293 { 294 if (lBufSize - lReadPos + lWritePos < MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) 295 { 296 SetEvent(hWriteEvent); 297 } 298 } 299 else 300 { 301 if (lWritePos - lReadPos < MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) 302 { 303 SetEvent(hWriteEvent); 304 } 305 } 306 307 return 0; 308 }
test.cpp
1 // Test.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "CircularBuf.h" 6 7 CCircularBuf test; 8 9 DWORD WINAPI writeThread(PVOID pvoid) 10 { 11 HANDLE hwite = (HANDLE)pvoid; 12 char pBuf[1024]; 13 long bytes = 0; 14 15 while(1) 16 { 17 if (WaitForSingleObject(hwite, 5000) == WAIT_OBJECT_0) 18 { 19 for (long i = 0; i < 1024; i++) 20 { 21 pBuf[i] = i % 0x7F; 22 } 23 bytes = test.writeBuf(pBuf, 1024); 24 printf("write byte %d\n", bytes); 25 } 26 else 27 { 28 printf("write wait time out\n"); 29 } 30 } 31 return 0; 32 } 33 34 DWORD WINAPI readThread(PVOID pvoid) 35 { 36 HANDLE hread = (HANDLE)pvoid; 37 char pBuf[1024]; 38 long realBytes = 0; 39 long bytes = 0; 40 long countByte = 0; 41 42 realBytes = test.readBuf(pBuf, 0); 43 44 while(1) 45 { 46 // if (WaitForSingleObject(hread, 5000) == WAIT_OBJECT_0) 47 // { 48 // bytes = rand() % 1024; 49 // realBytes = test.readBuf(pBuf, bytes); 50 // printf("read byte %d,real byte %d\n", bytes, realBytes); 51 // } 52 // else 53 // { 54 // printf("read wait time out\n"); 55 // } 56 57 //Sleep(1); 58 bytes = rand() % 1024; 59 realBytes = test.readBuf(pBuf, bytes); 60 printf("read byte %d,real byte %d\n", bytes, realBytes); 61 } 62 return 0; 63 } 64 65 int _tmain(int argc, _TCHAR* argv[]) 66 { 67 static long size = 1024; 68 HANDLE hwite, hread; 69 70 hwite = CreateEvent(NULL, FALSE, FALSE, NULL); 71 hread = CreateEvent(NULL, FALSE, FALSE, NULL); 72 73 test.createBuf(size, hwite, hread); 74 CreateThread(NULL, 0, writeThread, (LPVOID)hwite, 0, NULL); 75 CreateThread(NULL, 0, readThread, (LPVOID)hread, 0, NULL); 76 77 while(1) 78 { 79 Sleep(1000); 80 } 81 test.releaseBuf(); 82 return 0; 83 }