• 环形缓冲区类(C++)附测试程序(转)


    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

  • 相关阅读:
    mysql批量插入数据的基类
    mount命令解析
    常用linux命令记录
    转载一篇大神的博客文章
    linux查看网卡状态
    centos7配置网卡绑定
    coentos7安装python3
    阿里云ecs 硬盘在线扩容
    centos7安装redis5
    centos7 rpm安装nginx
  • 原文地址:https://www.cnblogs.com/donwu/p/3678620.html
Copyright © 2020-2023  润新知