线程安全的循环队列缓冲区

本文介绍了一种使用自定义可移植库xsys实现的循环队列类。该队列类不仅效率高,还提供了线程安全机制,适用于多线程环境的数据处理。

循环队列,效率比较高,原因是:不需要什么初始化、释放动作,循环利用。

但是,一般的容器类,比较复杂,更不提供线程安全。

 

这里,基于我自己编写的可移植库 xsys 编写了一个容器类,大家根据自己的编程环境,也很容易移植吧。如下:

 

#pragma once

#ifndef MAX_NODE
#define MAX_NODE 1024
#endif // MAX_NODE

#include <xsys.h> 

/*! \class circqueue
 *  循环队列类
 */
template<class T>
class  xcirc_queue{
public:
    xcirc_queue();
    ~xcirc_queue();

    int     open(int len = 512, int timeout_ms = 30000);
    void    close(void);

    int     in(T * x);
    int     out(T **cp);
    int     out(T * x);

protected:
    bool    isempty();
    bool    isfull();
    
    int     m_len;          /// 队列缓冲长度
    int     m_timeout_ms;   /// 取数据等待超时毫秒数

private:
    T *     m_pbuffer;  /// 队列
    int     m_head;     /// 队头
    int     m_tail;     /// 队尾
    
    xsys_semaphore  * m_psem;
    xsys_mutex * m_hmutex;
};

template<class T>
xcirc_queue<T>::xcirc_queue()
    : m_len(512)
    , m_timeout_ms(30000)
{
    m_head = 0;
    m_tail = 0;
    m_psem = 0;
    m_hmutex = 0;
}

template<class T>
xcirc_queue<T>::~xcirc_queue()
{
    close();
}

template<class T>
int xcirc_queue<T>::open(int len, int timeout_ms)
{
    if (len >= 16)
        m_len = len;
    if (timeout_ms >= 2000)
        m_timeout_ms = timeout_ms;

    m_pbuffer = (T *)malloc(sizeof(T) * m_len);
    if (m_pbuffer == 0)
        return -1;

    memset(m_pbuffer, 0x0, m_len * sizeof(T));

    m_psem = new xsys_semaphore;
    m_hmutex = new xsys_mutex;
    m_hmutex->init();
    
    return m_psem->init(0, m_len);
}

template<class T>
void xcirc_queue<T>::close(void)
{
    if (m_psem){
        m_psem->down();
        delete m_psem;
        m_psem = 0;
    }
    if (m_hmutex) {
        m_hmutex->down();
        delete m_hmutex;
        m_hmutex =0;
    }
    
    if (m_pbuffer){
        free(m_pbuffer);  m_pbuffer = 0;
    }
}

template<class T>
int xcirc_queue<T>::in(T * x)
{
    m_hmutex->lock(-1);

    if (isfull()){
        m_hmutex->unlock();
        return -1;
    }

    //printf("in : head[%d],tail[%d],id[%d]\n", m_head, m_tail, x.id);
    memcpy(m_pbuffer + m_tail, x, sizeof(T));

    m_tail = (m_tail + 1) % m_len;
    //printf("in : tail[%d] end.\n", m_tail);

    m_psem->V();
    
    m_hmutex->unlock();
    return 0;
}

template<class T>
int xcirc_queue<T>::out(T **cp)
{
    T * p = 0;

    if (m_psem->P(m_timeout_ms) != 0)
        return -1;

    m_hmutex->lock(-1);

    if (isempty())
    {
        m_hmutex->unlock();
        return -1;
    }

    //printf("out : head[%d],tail[%d]\n", m_head, m_tail);
    p = new T;
    memcpy(p, m_pbuffer+m_head, sizeof(T));
    *cp = p;

    m_head = (m_head + 1) % m_len;

    //printf("out : head[%d],id[%d]\n", m_head, p->id);
    
    m_hmutex->unlock();
    return 0;
}

template<class T>
int xcirc_queue<T>::out(T * x)
{
    T * p = 0;

    if (m_psem->P(m_timeout_ms) != 0)
        return -1;

    m_hmutex->lock(-1);

    if (isempty()){
        m_hmutex->unlock();
        return -1;
    }

    //printf("out : head[%d],tail[%d]\n", m_head, m_tail);
    memcpy(x, m_pbuffer+m_head, sizeof(T));

    m_head = (m_head + 1) % m_len;

    //printf("out : head[%d],id[%d]\n", m_head, p->id);
    m_hmutex->unlock();

    return 0;
}

template<class T>
bool xcirc_queue<T>::isempty()
{
    //printf("isempty : head[%d],tail[%d]\n", m_head, m_tail);
    return (m_head == m_tail)
}

template<class T>
bool xcirc_queue<T>::isfull()
{
    //printf("isfull : head[%d],tail[%d]\n", m_head, m_tail);
    return ((m_tail + 1) % m_len == m_head)
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值