自己写的一个环形缓冲区的c++类,附带测试程序

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 }

原文链接: https://www.cnblogs.com/ark-zhang/archive/2013/04/27/3046427.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/86184

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午10:26
下一篇 2023年2月9日 下午10:26

相关推荐