CircularBuf.h
#ifndef CIRCULAR_BUF_H #define CIRCULAR_BUF_H #include <Windows.h> #define MULTI_BUF_SIZE 10 #define MULTI_MIN_BUF_DATA_SIZE 5 class CCircularBuf { public: CCircularBuf(void); ~CCircularBuf(void); //创建缓冲区 long createBuf(const long size, const HANDLE writeEvent, const HANDLE readEvent); //释放缓冲区 long releaseBuf(void); //读 long readBuf(char *pBuf, const long bytes); //写 long writeBuf(const char *pBuf, const long bytes); private: //获取写指针 long getWritePos(const long size, long *pos1, long *pos2, long *len1, long *len2); //获取读指针 long getReadPos(const long size, long *pos1, long *pos2, long *len1, long *len2); //修改写指针 long setWritePos(const long pos); //修改读指针 long setReadPos(const long pos); private: char *pCirBuf; long lBufSize; long lMaxRWBufSize; long lWritePos; long lReadPos; HANDLE hWriteEvent; HANDLE hReadEvent; CRITICAL_SECTION csCirBuf; }; #endif
CircularBuf.cpp
#include "stdafx.h" #include "CircularBuf.h" CCircularBuf::CCircularBuf(void) { pCirBuf = NULL; lBufSize = 0; lMaxRWBufSize = 0; hWriteEvent = 0; hReadEvent = 0; lWritePos = 0; lReadPos = 0; } CCircularBuf::~CCircularBuf(void) { } //创建缓冲区 long CCircularBuf::createBuf(long size, const HANDLE writeEvent, const HANDLE readEvent) { if (!size || !writeEvent || !readEvent) { return -1; } pCirBuf = new char [size * MULTI_BUF_SIZE]; if (!pCirBuf) { return -1; } memset(pCirBuf, 0, size * MULTI_BUF_SIZE); lMaxRWBufSize = size; lBufSize = size * MULTI_BUF_SIZE; hWriteEvent = writeEvent; hReadEvent = readEvent; lWritePos = 0; lReadPos = 0; InitializeCriticalSection(&csCirBuf); return 0; } //释放缓冲区 long CCircularBuf::releaseBuf(void) { if (!lBufSize) { return -1; } EnterCriticalSection(&csCirBuf); if (pCirBuf) { delete []pCirBuf; pCirBuf = NULL; } lMaxRWBufSize = 0; lBufSize = 0; hWriteEvent = 0; hReadEvent = 0; lWritePos = 0; lReadPos = 0; LeaveCriticalSection(&csCirBuf); DeleteCriticalSection(&csCirBuf); return 0; } //读 long CCircularBuf::readBuf(char *pBuf, const long bytes) { long pos1 = 0; long pos2 = 0; long len1 = 0; long len2 = 0; long realBytes = 0; if (bytes > lMaxRWBufSize || !pBuf) { return -1; } EnterCriticalSection(&csCirBuf); if (getReadPos(bytes, &pos1, &pos2, &len1, &len2)) { LeaveCriticalSection(&csCirBuf); return -1; } if (pos2) { memcpy(pBuf, &pCirBuf[pos1], len1); realBytes = len1; setReadPos(pos1 + len1); } else { memcpy(pBuf, &pCirBuf[pos1], len1); memcpy(&pBuf[len1], &pCirBuf, len2); realBytes = len1 + len2; setReadPos(len2); } LeaveCriticalSection(&csCirBuf); return realBytes; } //写 long CCircularBuf::writeBuf(const char *pBuf, const long bytes) { long pos1 = 0; long pos2 = 0; long len1 = 0; long len2 = 0; long writeBytes = 0; if (bytes > lMaxRWBufSize || !pBuf) { return -1; } EnterCriticalSection(&csCirBuf); if (getWritePos(bytes, &pos1, &pos2, &len1, &len2)) { LeaveCriticalSection(&csCirBuf); return -1; } if (pos2) { memcpy(&pCirBuf[pos1], pBuf, len1); writeBytes = len1; setWritePos(pos1 + len1); } else { memcpy(&pCirBuf[pos1], pBuf, len1); memcpy(&pCirBuf, &pBuf[len1], len2); writeBytes = len1 + len2; setWritePos(len2); } LeaveCriticalSection(&csCirBuf); return writeBytes; } //获取写指针 long CCircularBuf::getWritePos(const long size, long *pos1, long *pos2, long *len1, long *len2) { if (!pos1 || !pos2 || *len1 || *len2) { return -1; } *pos1 = lWritePos; if (lWritePos < lReadPos)//写指针在读指针左,不可能循环 { *pos2 = lBufSize; *len2 = 0; if (lWritePos + size > lReadPos) { *len1 = lReadPos - lWritePos; } else { *len1 = size; } } else//写指针在读指针右,可能循环 { if (lWritePos + size > lBufSize) { *len1 = lBufSize - lWritePos; *pos2 = 0; *len2 = size + lWritePos - lBufSize; if (*len2 > lReadPos) { *len2 = lReadPos; } } else { *len1 = size; *pos2 = lBufSize; *len2 = 0; } } return 0; } //获取读指针 long CCircularBuf::getReadPos(const long size, long *pos1, long *pos2, long *len1, long *len2) { if (!pos1 || !pos2 || *len1 || *len2) { return -1; } *pos1 = lReadPos; if (lReadPos <= lWritePos)//读指针在写指针左,不可能循环 { *pos2 = lBufSize; *len2 = 0; if (lReadPos + size > lWritePos) { *len1 = lWritePos - lReadPos; } else { *len1 = size; } } else//读指针在写指针右,可能循环 { if (lReadPos + size > lBufSize) { *len1 = lBufSize - lReadPos; *pos2 = 0; *len2 = size + lReadPos - lBufSize; if (*len2 > lWritePos) { *len2 = lWritePos; } } else { *len1 = size; *pos2 = lBufSize; *len2 = 0; } } return 0; } //修改写指针 long CCircularBuf::setWritePos(const long pos) { if (pos >= lBufSize) { lWritePos = pos - lBufSize; } else { lWritePos = pos; } if (lReadPos > lWritePos) { if (lBufSize - lReadPos + lWritePos > MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) { SetEvent(hReadEvent); } } else { if (lWritePos - lReadPos > MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) { SetEvent(hReadEvent); } } return 0; } //修改读指针 long CCircularBuf::setReadPos(const long pos) { if (pos >= lBufSize) { lReadPos = pos - lBufSize; } else { lReadPos = pos; } if (lReadPos > lWritePos) { if (lBufSize - lReadPos + lWritePos < MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) { SetEvent(hWriteEvent); } } else { if (lWritePos - lReadPos < MULTI_MIN_BUF_DATA_SIZE * lMaxRWBufSize) { SetEvent(hWriteEvent); } } return 0; }
test.cpp
// Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "CircularBuf.h" CCircularBuf test; DWORD WINAPI writeThread(PVOID pvoid) { HANDLE hwite = (HANDLE)pvoid; char pBuf[1024]; long bytes = 0; while(1) { if (WaitForSingleObject(hwite, 5000) == WAIT_OBJECT_0) { for (long i = 0; i < 1024; i++) { pBuf[i] = i % 0x7F; } bytes = test.writeBuf(pBuf, 1024); printf("write byte %d ", bytes); } else { printf("write wait time out "); } } return 0; } DWORD WINAPI readThread(PVOID pvoid) { HANDLE hread = (HANDLE)pvoid; char pBuf[1024]; long realBytes = 0; long bytes = 0; long countByte = 0; realBytes = test.readBuf(pBuf, 0); while(1) { // if (WaitForSingleObject(hread, 5000) == WAIT_OBJECT_0) // { // bytes = rand() % 1024; // realBytes = test.readBuf(pBuf, bytes); // printf("read byte %d,real byte %d ", bytes, realBytes); // } // else // { // printf("read wait time out "); // } //Sleep(1); bytes = rand() % 1024; realBytes = test.readBuf(pBuf, bytes); printf("read byte %d,real byte %d ", bytes, realBytes); } return 0; } int _tmain(int argc, _TCHAR* argv[]) { static long size = 1024; HANDLE hwite, hread; hwite = CreateEvent(NULL, FALSE, FALSE, NULL); hread = CreateEvent(NULL, FALSE, FALSE, NULL); test.createBuf(size, hwite, hread); CreateThread(NULL, 0, writeThread, (LPVOID)hwite, 0, NULL); CreateThread(NULL, 0, readThread, (LPVOID)hread, 0, NULL); while(1) { Sleep(1000); } test.releaseBuf(); return 0; }
原帖地址:http://www.cnblogs.com/ark-zhang/archive/2013/04/27/3046427.html