循环缓冲区
来源:互联网 发布: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;}
在此基础上可以写一个带扩展空间的循环缓冲区
阅读全文
0 0
- 循环缓冲区
- 循环缓冲区
- 循环缓冲区
- 循环缓冲区类
- 键盘输入循环缓冲区问题
- 队列实现循环缓冲区
- 循环缓冲区的定义
- boost 循环缓冲区
- Linux中的循环缓冲区
- Android 循环缓冲区
- 队列实现循环缓冲区
- C++版循环缓冲区类
- 循环缓冲区的一点笔记
- Linux内核中的循环缓冲区
- Linux内核中的循环缓冲区
- linux内核中的循环缓冲区
- 循环缓冲区(数据块)
- 串口实用的循环缓冲区
- 五分钟学GIS | 自己动手做Docker镜像
- <trim>: prefix+prefixOverrides+suffix+suffixOverrides
- fabric调试:go pprof查看内存
- VisualSVN Server设置AD域账号自动验证登录
- 20170720随笔
- 循环缓冲区
- 销售订单 条件记录隐藏
- jsp页面写java代码
- awk if else
- 编译安卓Linux内核并替换(配置支持LKM)
- java.lang.NoSuchMethodError
- 使用 LinkedHashMap 实现 LRU 算法
- elasticsearch5.x的java实现搜索
- JAVA笔记--复用类