lockfree 的队列的实现

一个高速无锁循环队列的实现。需要注意的是:(1)队列的大小(m_lMaxQueueSize)应该足够的大,避免处理不过来时,找半天找不到空位置。(2)还有一点是这种队列在push数据足够快时效率高点,不然pop时就阻塞了,改善的方式就是使用费阻塞的方式,判断几次没有就跳出去,还有这种队列也就在push数据足够快时效率高点,不然判断的次数就多了。(3)使用了原子操作的锁(4)需...
摘要由CSDN通过智能技术生成

一个高速无锁循环队列的实现。

需要注意的是:

(1)队列的大小(m_lMaxQueueSize)应该足够的大,避免处理不过来时,找半天找不到空位置。

(2)还有一点是这种队列在push数据足够快时效率高点,不然pop时就阻塞了,改善的方式就是使用费阻塞的方式,判断几次没有就跳出去,还有这种队列也就在push数据足够快时效率高点,不然判断的次数就多了。 

(3)使用了原子操作的锁

(4)需要优化的的是数值开始与结束之间长度小于阈值就不取。

代码如下:

 

// 临界锁,线程安全  
// 必须要有一个不会用的空值
typedef unsigned int var_4;
typedef unsigned long var_u8;

template <class T_Key>  //队列里的值
class CQueue_Lockfree  
{  
public:  
    CQueue_Lockfree()  
    {  
        m_lMaxQueueSize = -1;  
        m_tpQueue = NULL;  //队列的内存
        m_lBegPos = 0;  //队列的开始位置
        m_lEndPos = 0;  //队列的结束位置
    };  
    ~CQueue_Lockfree()  
    {  
        if(m_tpQueue)  
            delete m_tpQueue;  
    };  
    var_4 InitQueue(var_4 lMaxQueueSize, T_Key null)//null为空的值(目前为0)
    {  
        m_lMaxQueueSize = lMaxQueueSize;  
        m_tpQueue = new T_Key[m_lMaxQueueSize];  
        if(m_tpQueue == NULL)  
            return -1;  
        m_lBegPos = 0;  
        m_lEndPos = 0;  
        m_null = null;  
        for( var_4 i = 0; i < lMaxQueueSize; i++ )  
        {  
            m_tpQueue[i] = null;  
        }  
        return 0;  
    };  
  
    void ResetQueue()  
    {  
        m_lBegPos = 0;  
        m_lEndPos = 0;    
    };  
  
    void ClearQueue()  
    {  
        if(m_tpQueue)  
        {  
            delete m_tpQueue;  
            m_tpQueue = NULL;  
        }  
        m_lMaxQueueSize = -1;  
        m_lBegPos = 0;  
        m_lEndPos = 0;  
    };  
    void PushData(T_Key tKey)  
    {  
        register var_u8 cnt = 1;  
        var_u8 pos = fetch_and_add(&m_lEndPos, cnt)%m_lMaxQueueSize;  //队列的m_lEndPos位置下一个位置
        while( m_null != m_tpQueue[pos] )  //等到该位置为空才能放数值
            cp_sleep(1);  
        m_tpQueue[pos] = tKey;  
    };  
  
    T_Key PopData()  
    {  
        register var_u8 cnt =1;  
        var_u8 pos = fetch_and_add(&m_lBegPos, cnt)%m_lMaxQueueSize;  //队列的m_lBegPos位置下一个位置
        T_Key *p = m_tpQueue + pos;  
        while( m_null == *p )  //等到该位置不为空才能取数值
            cp_sleep(1);  
  
        T_Key ret = *p;  
        *p = m_null;  
        return ret;  
    };  
private:  
    var_4 m_lMaxQueueSize;  
    T_Key* m_tpQueue;  
    T_Key m_null;  
  
    var_u4 m_lBegPos;  
    var_u4 m_lEndPos;  
};  


别人的测试结果,这种方式比用锁少了40%。

 

10亿次放入和读取,10线程花费200秒。

测试说加了阈值判断后说是8核1.5GHz花了88秒,没加前是

24核机器200秒

vendor_id       : GenuineIntel
cpu family   

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值