循环缓冲区

来源:互联网 发布:109魔化生秒数据图 编辑:程序博客网 时间:2024/05/29 06:27

#ifndef _MSGBUFFER_H_#define _MSGBUFFER_H_#ifdef __cplusplusextern "C" {#endif#ifdef __cplusplus}#endif#include <pthread.h>#include <stdlib.h>#include "ace/Thread_Mutex.h"#include "ace/RW_Thread_Mutex.h"#include "ace/Time_Value.h"#define QUEUE_SIZE (1024 * 1024 * 3 / 2)class MsgDataBuffer{public:MsgDataBuffer(size_t size = QUEUE_SIZE );~MsgDataBuffer();/** * @ func:  readn* @ brief:  读取指定个数的元素到目标缓冲区中* * @author iFLYTEK* Access: public * @return: int 出错返回-1;否则返回已经读取的元素个数* @param: short * buf [-out]* @param: size_t count* @param: const struct timespec * timeout 读取单个元素的最大时延 * @see*/int readn(short* buf, size_t count, const struct timespec *timeout = NULL);/** * @ func:  writen* @ brief:  将缓冲区写入(当有一个元素延时超过指定时延时,即返回)* * @author iFLYTEK* Access: public * @return: int  出错返回-1;否则,返回写入的元素个数* @param: const short * buf* @param: size_t count* @param: const struct timespec * timeout 延时 写入单个元素的最大时延(为0表示不等待)* @see*/int writen(const short* buf, size_t count, const struct timespec *timeout = NULL);/** * @ func:  isEmpty* @ brief:  判定是否为空* * @author iFLYTEK* Access: public * @return: bool true:空; false:不空* @see*/bool isEmpty();/** * @ func:  size* @ brief:  返回缓冲区中元素个数* * @author iFLYTEK* Access: public * @return: size_t* @see*/size_t size();/** * @ func:  size_for_fill* @ brief:  为了填充静音而先获取当前长度,(不允许存在非法读)* * @author iFLYTEK* Access: public * @return: size_t* @see*/size_t size_for_fill();/** * @ func:  isFull* @ brief:  缓冲区是否满了* * @author iFLYTEK* Access: public * @return: bool true:满;false:不满* @see*/bool isFull();bool is_time_out();void set_begin_time();void clear();protected:private:size_t m_head;  //队头size_t m_tail;  //队尾ACE_Thread_Mutex       get_lock_;ACE_Thread_Mutex       put_lock_;ACE_Time_Value         latest_write_time_;short * m_buffer;  //缓冲区首地址int                    time_out_interval_;  //通道超时时间间隔};#endif  //_MSGBUFFER_H_



#include <memory.h>#include <iostream>#include "msgBuffer.h"#include "../busin_common/busin_log.h"#include "ace/Thread_Mutex.h"#include "Mix_Check_Task.h"#include "../busin_common/busin_config.h"using namespace std;MsgDataBuffer::MsgDataBuffer(size_t size /*= QUEUE_SIZE */):latest_write_time_(ACE_OS::gettimeofday()){businlog_tracer(MsgDataBuffer::MsgDataBuffer);m_buffer = (short *) new short[size];memset(m_buffer, 0, size * sizeof(short));m_head = 0;m_tail = 0;time_out_interval_ = Busin_Conf_Instance()->get_int_val("mix_common", "channel_time_out", 2);businlog_info("MsgDataBuffer::MsgDataBuffer | channel_time_out is %d", time_out_interval_);    }MsgDataBuffer::~MsgDataBuffer(){businlog_tracer(MsgDataBuffer::~MsgDataBuffer);if (NULL != m_buffer){delete[] m_buffer;m_buffer = NULL;}}int MsgDataBuffer::readn(short* buf, size_t count, const struct timespec *timeout){businlog_tracer(MsgDataBuffer::readn);if ( NULL== buf){return -1;}ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, get_lock_, -1);size_t idx = 0;for (idx=0; idx <count; ++idx){if (isEmpty()){return idx;}buf[idx] = m_buffer[m_head];m_head = (m_head + 1) % QUEUE_SIZE;}return count;}int MsgDataBuffer::writen(const short* buf, size_t count, const struct timespec *timeout){businlog_tracer(MsgDataBuffer::writen);if ( !buf){businlog_error("MsgDataBuffer::writen | buff is null");return -1;}ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, put_lock_, -1);//此时空间充足size_t idx = 0;latest_write_time_ = ACE_OS::gettimeofday();for (idx=0; idx < count; ++idx){if (isFull()){businlog_error("MsgDataBuffer::writen |  is full ");return idx;}m_buffer[m_tail] = buf[idx];m_tail = (m_tail + 1) % QUEUE_SIZE;}return count;}bool MsgDataBuffer::isEmpty(){return m_head == m_tail;}size_t MsgDataBuffer::size(){//获取长度时,禁止读写// ACE_GUARD_RETURN(ACE_Thread_Mutex, guard_write, put_lock_, 0);// ACE_GUARD_RETURN(ACE_Thread_Mutex, guard_read, get_lock_, 0);size_t sum = (m_tail  + QUEUE_SIZE - m_head) % QUEUE_SIZE; //允许存在非法读return sum;}size_t MsgDataBuffer::size_for_fill(){ACE_GUARD_RETURN(ACE_Thread_Mutex, guard_write, put_lock_, 0);ACE_GUARD_RETURN(ACE_Thread_Mutex, guard_read, get_lock_, 0);size_t sum = (m_tail  + QUEUE_SIZE - m_head) % QUEUE_SIZE; return sum;}bool MsgDataBuffer::isFull(){return ((m_tail + 1) % QUEUE_SIZE == m_head);}bool MsgDataBuffer::is_time_out(){businlog_tracer(MsgDataBuffer::is_time_out);ACE_Time_Value now_t, interval;now_t = ACE_OS::gettimeofday();interval = now_t - latest_write_time_;if( interval.sec() >=  time_out_interval_){return true;}else{return false;}}void MsgDataBuffer::set_begin_time(){latest_write_time_ = ACE_OS::gettimeofday();}void MsgDataBuffer::clear(){m_head = 0;m_tail = 0;}

在此基础上可以写一个带扩展空间的循环缓冲区


原创粉丝点击