关闭

环形缓冲区类(C++源码

219人阅读 评论(0) 收藏 举报
分类:

环形缓冲区类(C++源码)绝对可用  

2012-12-06 21:04:05|  分类: C/C++ |  标签:环形缓冲区  循环缓冲区  缓冲区  c++  qbuffer   |举报 |字号 订阅

       参考网络循环缓冲区类源码,修改了作者的两个bug,经测试,可以实现多线程并发读写。数据准确无误。
多线程并行读写环形缓冲区源代码例子
代码例子下载2环形缓冲区QT代码(多线程+互斥锁+等待条件)
理论如下:
环形缓冲区类(C++源码)绝对可用 - 柳北风儿 - 柳北风儿~~~~~~~欲宇仙炅
 
源码如下:
头文件CCycleBuffer.h 
  1. /** 
  2. * 项    目   xxxx软件  
  3. * 模    块   FPGA 
  4. * 文件名称   CCycleBuffer.h 
  5. * 文件路径   FPGA/CCycleBuffer.h 
  6. * 摘    要   FPGA的循环缓冲区类 
  7. * 作    者   xxx 
  8. * 完成日期   2012年12月07日 
  9. * Copyright (c) 2011~2012, 中科院*************组. 
  10. * All rights reserved. 
  11. * Version v1.0 
  12. */  
  13. #ifndef CCycleBuffer_H  
  14. #define CCycleBuffer_H  
  15. #include <QMutex>  
  16. class CCycleBuffer  
  17. {  
  18.   
  19. public:  
  20.     /**  
  21.      *  function 构造函数 
  22.      *  @param   size    缓冲区大小默认1M, 
  23.      *                   也可以通过setBufferSize(int size)进行重置缓冲区大小, 
  24.      *                   但是一定要在缓冲区为空的前提下,否则会丢失已有数据。 
  25.      *  @param   port  端口 
  26.      *  @return  bool  返回状态 
  27.      *                 true,成功; false,失败 
  28.      *  @author  Liuzhaobang 
  29.      *  @date    2012-12-7 
  30.      */  
  31.     CCycleBuffer(int size = 1024*1024);  
  32.     virtual ~CCycleBuffer();  
  33.     int write(char* buf, int count);  
  34.     int read(char* buf, int count);  
  35.       
  36.     /**  
  37.      *  function 缓冲区是否已满? 
  38.      *  @return  bool  返回状态 
  39.      *                 true,真; false,假 
  40.      *  @author  Liuzhaobang 
  41.      *  @date    2012-12-7 
  42.      */  
  43.     bool isFull();  
  44.     /**  
  45.      *  function 缓冲区是否空? 
  46.      *  @return  bool  返回状态 
  47.      *                 true,真; false,假 
  48.      *  @author  Liuzhaobang 
  49.      *  @date    2012-12-7 
  50.      */  
  51.     bool isEmpty();  
  52.     /**  
  53.      *  function 设置缓冲区为空 
  54.      *  @return  bool  返回状态 
  55.      *                 true,真; false,假 
  56.      *  @author  Liuzhaobang 
  57.      *  @date    2012-12-7 
  58.      */  
  59.     void setEmpty();  
  60.     /**  
  61.      *  function 返回当前缓冲区已用空间 
  62.      *  @return  int   返回已用空间大小(byte) 
  63.      *  @author  Liuzhaobang 
  64.      *  @date    2012-12-7 
  65.      */  
  66.     int getUsedSize();  
  67.     /**  
  68.      *  function 返回当前缓冲区可用空间 
  69.      *  @return  int   返回空闲空间大小(byte) 
  70.      *  @author  Liuzhaobang 
  71.      *  @date    2012-12-7 
  72.      */  
  73.     int getFreeSize();    
  74.     /**  
  75.      *  function 返回缓冲空间大小 
  76.      *  @return  int   返回缓冲空间大小 
  77.      *  @author  Liuzhaobang 
  78.      *  @date    2012-12-7 
  79.      */  
  80.     int getBufSize()  
  81.     {  
  82.         return m_nBufSize;  
  83.     }  
  84.     /**  
  85.      *  function 返回缓冲空间开始位置 
  86.      *  @return  int   返回缓冲空间开始位置 
  87.      *  @author  Liuzhaobang 
  88.      *  @date    2012-12-7 
  89.      */  
  90.     int getStart()  
  91.     {  
  92.         return m_nReadPos;  
  93.     }  
  94.     /**  
  95.      *  function 返回缓冲空间结束位置 
  96.      *  @return  int   返回缓冲空间结束位置 
  97.      *  @author  Liuzhaobang 
  98.      *  @date    2012-12-7 
  99.      */  
  100.     int getEnd()  
  101.     {  
  102.         return m_nWritePos;  
  103.     }  
  104.     /**  
  105.      *  function 设置缓冲区大小 
  106.      *  @param   size   新开辟缓冲区大小 
  107.      *  @param   copy   是否拷贝已有数据至新缓冲区,默认false,不拷贝. 
  108.      *  @return  bool   返回状态 
  109.      *                  true,真; false,假 
  110.      *  @author  Liuzhaobang 
  111.      *  @date    2012-12-7 
  112.      */  
  113.     bool setBufferSize(int size, bool copy = false);  
  114.   
  115. private:  
  116.     //空标示符  
  117.     bool m_bEmpty;  
  118.     //满标示符  
  119.     bool m_bFull;  
  120.     //缓冲区指针  
  121.     char * m_pBuf;  
  122.     //缓冲区大小  
  123.     int m_nBufSize;  
  124.     //始位置  
  125.     int m_nReadPos;  
  126.     //尾位置  
  127.     int m_nWritePos;  
  128. };  
  129. #endif // CCycleBuffer_H  


========================================================

源文件CCycleBuffer.cpp:


  1. #include "CCycleBuffer.h"  
  2. #include <assert.h>  
  3. #include <memory.h>  
  4. #include <QDebug>  
  5.   
  6. CCycleBuffer::CCycleBuffer(int size)  
  7.   
  8. {    
  9.     m_nBufSize = size;    
  10.     m_nReadPos = 0;    
  11.     m_nWritePos = 0;    
  12.     m_pBuf = new char[m_nBufSize];  
  13.     m_bEmpty = true;    
  14.     m_bFull = false;   
  15. }    
  16. CCycleBuffer::~CCycleBuffer()    
  17. {    
  18.     delete[] m_pBuf;    
  19. }   
  20.   
  21. /* 
  22.  *  函数介绍  向缓冲区写入数据,返回实际写入的字节数  
  23.  */  
  24. int CCycleBuffer::write(char* buf, int count)    
  25. {    
  26.     if(count <= 0)   
  27.         return 0;    
  28.     m_bEmpty = false;    
  29.     // 缓冲区已满,不能继续写入    
  30.     if(m_bFull)     
  31.     {    
  32.         return 0;    
  33.     }    
  34.     else if(m_nReadPos == m_nWritePos) // 缓冲区为空时    
  35.     {    
  36.         /*                          == 内存模型 ==  
  37.                  (empty)             m_nReadPos                (empty)                        
  38.         |----------------------------------|-----------------------------------------|  
  39.                                     m_nWritePos        m_nBufSize  
  40.         */    
  41.         int leftcount = m_nBufSize - m_nWritePos;    
  42.         if(leftcount > count)    
  43.         {    
  44.             memcpy(m_pBuf + m_nWritePos, buf, count);    
  45.             m_nWritePos += count;    
  46.             m_bFull = (m_nWritePos == m_nReadPos);    
  47.             return count;    
  48.         }    
  49.         else    
  50.         {    
  51.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);    
  52.             m_nWritePos = (m_nReadPos > count - leftcount) ? count - leftcount : m_nWritePos;    
  53.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);    
  54.             m_bFull = (m_nWritePos == m_nReadPos);    
  55.             return leftcount + m_nWritePos;    
  56.         }    
  57.     }     
  58.     else if(m_nReadPos < m_nWritePos) // 有剩余空间可写入    
  59.     {    
  60.         /*                           == 内存模型 ==  
  61.             (empty)                 (data)                     (empty)  
  62.         |-------------------|----------------------------|---------------------------|  
  63.                     m_nReadPos                m_nWritePos       (leftcount)             
  64.         */    
  65.         // 剩余缓冲区大小(从写入位置到缓冲区尾)    
  66.   
  67.         int leftcount = m_nBufSize - m_nWritePos;  
  68.         if(leftcount > count)   // 有足够的剩余空间存放    
  69.         {    
  70.             memcpy(m_pBuf + m_nWritePos, buf, count);    
  71.             m_nWritePos += count;    
  72.             m_bFull = (m_nReadPos == m_nWritePos);    
  73.             assert(m_nReadPos <= m_nBufSize);    
  74.             assert(m_nWritePos <= m_nBufSize);        
  75.             return count;    
  76.         }    
  77.         else       // 剩余空间不足    
  78.         {    
  79.             // 先填充满剩余空间,再回头找空间存放    
  80.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);   
  81.   
  82.             m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nReadPos;    
  83.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);    
  84.             m_bFull = (m_nReadPos == m_nWritePos);       
  85.             assert(m_nReadPos <= m_nBufSize);    
  86.             assert(m_nWritePos <= m_nBufSize);     
  87.             return leftcount + m_nWritePos;    
  88.         }    
  89.     }    
  90.     else    
  91.     {    
  92.         /*                          == 内存模型 ==  
  93.             (unread)                 (read)                     (unread)  
  94.         |-------------------|----------------------------|---------------------------|  
  95.                      m_nWritePos    (leftcount)    m_nReadPos                        
  96.         */    
  97.         int leftcount = m_nReadPos - m_nWritePos;    
  98.         if(leftcount > count)    
  99.         {    
  100.             // 有足够的剩余空间存放    
  101.             memcpy(m_pBuf + m_nWritePos, buf, count);    
  102.             m_nWritePos += count;    
  103.             m_bFull = (m_nReadPos == m_nWritePos);    
  104.             assert(m_nReadPos <= m_nBufSize);    
  105.             assert(m_nWritePos <= m_nBufSize);     
  106.             return count;    
  107.         }    
  108.         else    
  109.         {    
  110.             // 剩余空间不足时要丢弃后面的数据    
  111.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);    
  112.             m_nWritePos += leftcount;    
  113.             m_bFull = (m_nReadPos == m_nWritePos);    
  114.             assert(m_bFull);    
  115.             assert(m_nReadPos <= m_nBufSize);    
  116.             assert(m_nWritePos <= m_nBufSize);       
  117.             return leftcount;    
  118.         }    
  119.     }    
  120. }    
  121. /* 
  122.  *  函数介绍  从缓冲区读数据,返回实际读取的字节数  
  123.  */  
  124. int CCycleBuffer::read(char* buf, int count)    
  125. {    
  126.     if(count <= 0)   
  127.         return 0;    
  128.     m_bFull = false;    
  129.     if(m_bEmpty)       // 缓冲区空,不能继续读取数据    
  130.     {    
  131.         return 0;    
  132.     }    
  133.     else if(m_nReadPos == m_nWritePos)   // 缓冲区满时    
  134.     {    
  135.         /*                          == 内存模型 ==  
  136.          (data)          m_nReadPos                (data)      
  137.         |--------------------------------|--------------------------------------------|  
  138.              m_nWritePos         m_nBufSize  
  139.         */    
  140.         int leftcount = m_nBufSize - m_nReadPos;    
  141.         if(leftcount > count)    
  142.         {    
  143.             memcpy(buf, m_pBuf + m_nReadPos, count);    
  144.             m_nReadPos += count;    
  145.             m_bEmpty = (m_nReadPos == m_nWritePos);    
  146.             return count;    
  147.         }    
  148.         else    
  149.         {    
  150.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);    
  151.             m_nReadPos = (m_nWritePos > count - leftcount) ? count - leftcount : m_nWritePos;    
  152.             memcpy(buf + leftcount, m_pBuf, m_nReadPos);    
  153.             m_bEmpty = (m_nReadPos == m_nWritePos);    
  154.             return leftcount + m_nReadPos;    
  155.         }    
  156.     }    
  157.     else if(m_nReadPos < m_nWritePos)   // 写指针在前(未读数据是连接的)    
  158.     {    
  159.         /*                          == 内存模型 ==  
  160.             (read)                 (unread)                      (read)      
  161.         |-------------------|----------------------------|---------------------------|  
  162.                     m_nReadPos                m_nWritePos                     m_nBufSize  
  163.         */    
  164.         int leftcount = m_nWritePos - m_nReadPos;    
  165.         int c = (leftcount > count) ? count : leftcount;    
  166.         memcpy(buf, m_pBuf + m_nReadPos, c);    
  167.         m_nReadPos += c;    
  168.         m_bEmpty = (m_nReadPos == m_nWritePos);    
  169.         assert(m_nReadPos <= m_nBufSize);    
  170.         assert(m_nWritePos <= m_nBufSize);    
  171.         return c;    
  172.     }    
  173.     else          // 读指针在前(未读数据可能是不连接的)    
  174.     {    
  175.         /*                          == 内存模型 ==  
  176.               (unread)                (read)                      (unread)  
  177.         |-------------------|----------------------------|---------------------------|  
  178.                      m_nWritePos                  m_nReadPos                  m_nBufSize  
  179.  
  180.         */    
  181.         int leftcount = m_nBufSize - m_nReadPos;    
  182.         if(leftcount > count)   // 未读缓冲区够大,直接读取数据    
  183.         {    
  184.             memcpy(buf, m_pBuf + m_nReadPos, count);    
  185.             m_nReadPos += count;    
  186.             m_bEmpty = (m_nReadPos == m_nWritePos);    
  187.             assert(m_nReadPos <= m_nBufSize);    
  188.             assert(m_nWritePos <= m_nBufSize);    
  189.             return count;    
  190.         }    
  191.         else       // 未读缓冲区不足,需回到缓冲区头开始读    
  192.         {    
  193.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);    
  194.             m_nReadPos = (m_nWritePos >= count - leftcount) ? count - leftcount : m_nWritePos;    
  195.             memcpy(buf + leftcount, m_pBuf, m_nReadPos);    
  196.             m_bEmpty = (m_nReadPos == m_nWritePos);    
  197.             assert(m_nReadPos <= m_nBufSize);    
  198.             assert(m_nWritePos <= m_nBufSize);    
  199.             return leftcount + m_nReadPos;    
  200.         }      
  201.     }    
  202. }   
  203.   
  204. bool CCycleBuffer::isFull()    
  205. {    
  206.     return m_bFull;    
  207. }     
  208. bool CCycleBuffer::isEmpty()    
  209. {    
  210.     return m_bEmpty;    
  211. }    
  212.   
  213. void CCycleBuffer::setEmpty()    
  214. {    
  215.     m_nReadPos = 0;    
  216.     m_nWritePos = 0;    
  217.     m_bEmpty = true;    
  218.     m_bFull = false;    
  219. }    
  220.   
  221. /** 
  222.  * 获取缓冲区有效数据长度 
  223.  */  
  224. int CCycleBuffer::getUsedSize()    
  225. {    
  226.     if(m_bEmpty)    
  227.     {    
  228.         return 0;    
  229.     }    
  230.     else if(m_bFull)    
  231.     {    
  232.         return m_nBufSize;    
  233.     }    
  234.     else if(m_nReadPos < m_nWritePos)    
  235.     {    
  236.         return m_nWritePos - m_nReadPos;    
  237.     }    
  238.     else    
  239.     {    
  240.         return m_nBufSize - m_nReadPos + m_nWritePos;    
  241.     }    
  242. }  
  243. /** 
  244.  * 获取缓冲区空闲空间数据长度 
  245.  */  
  246. int CCycleBuffer::getFreeSize()   
  247. {    
  248.     if(m_bEmpty)    
  249.     {    
  250.         return m_nBufSize;    
  251.     }    
  252.     else if(m_bFull)    
  253.     {    
  254.         return 0;    
  255.     }    
  256.     else if(m_nReadPos > m_nWritePos)    
  257.     {    
  258.         return m_nReadPos - m_nWritePos;    
  259.     }    
  260.     else    
  261.     {    
  262.         return m_nBufSize - m_nWritePos + m_nReadPos;    
  263.     }    
  264. }  
  265.   
  266.  /* 
  267.   * @brief  设置缓冲区大小 
  268.   *           若没有缓冲区,则新建缓冲区;若已有缓冲区,则新建缓冲区并按照copy标志,进行旧数据拷贝 
  269.   */  
  270.  bool CCycleBuffer::setBufferSize(int size, bool copy)  
  271.  {  
  272.      //若已有空间,释放掉。开辟新缓冲区,并进行拷贝旧数据  
  273.      if(m_pBuf!=0)  
  274.      {  
  275.            
  276.          //新开辟缓冲区  
  277.          char* buf = new char(size);  
  278.          //若需要拷贝  
  279.          if(copy)  
  280.          {  
  281.              if(size <= m_nBufSize)  
  282.                {  
  283.                  //拷贝旧数据  
  284.                  memcpy(buf, m_pBuf,size);  
  285.                  qDebug("CCycleBuffer::setBufferSize,重置缓冲区,开辟空间小于原先旧空间,会丢失数据。");  
  286.                 }  
  287.              else  
  288.                  memcpy(buf, m_pBuf,m_nBufSize);  
  289.          }  
  290.          //释放旧缓冲区  
  291.          delete m_pBuf;  
  292.          //指向新缓冲区  
  293.          m_pBuf = buf;  
  294.          //重置缓冲区大小  
  295.          m_nBufSize = size;  
  296.      }  
  297.      //若没有缓冲区,则开辟缓冲区  
  298.      else  
  299.      {  
  300.          //新开辟缓冲区  
  301.          m_pBuf = new char(size);  
  302.          //赋值缓冲区大小  
  303.          m_nBufSize = size;  
  304.      }  
  305.   
  306.      if(m_pBuf!=0)  
  307.         return true;  
  308.      else  
  309.         return false;  
  310.  }  
  311.    

 


 附上原文链接:原文代码有错,请注意。

http://blog.csdn.net/favormm/article/details/5258697

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:160144次
    • 积分:2286
    • 等级:
    • 排名:第17014名
    • 原创:0篇
    • 转载:412篇
    • 译文:0篇
    • 评论:9条
    最新评论