无锁并发队列

参考论文 Implementing Lock-Free Queues

ConQueue实现了无锁并发循环队列,采用数组存储队列的数据。

con_queue.hpp

#ifndef CON_QUEUE_H_
#define CON_QUEUE_H_

#include <atomic>
#include <vector>

using namespace std;
namespace eventsock{

template<typename T>
class ConQueue{
private:
        T*                      m_data;  //存储队列节点的数组
        int                     m_data_len;  //数组m_data的长度
        int                     m_tail;
        int                     m_head;
        atomic_uint     m_size;

public:

        ConQueue(T* data, int data_len): m_tail(0), m_size(0){
                m_data = data;
                m_data_len = data_len;
                // m_head表示第一个元素
                m_head = 0;
                // m_tail标记队列尾部,不包含元素
                m_tail = 0;
        }

        bool push(T value){
                int old_tail, new_tail;
                while(true){
                        old_tail = m_tail;
                        new_tail = (old_tail + 1) % m_data_len;
                        //队列已满
                        if(new_tail == m_head) return false;
                        if(__sync_bool_compare_and_swap(&m_tail, old_tail, new_tail)){  
                                m_data[old_tail] = value;
                                m_size++;
                                break;
                        }
                }
                return true;
        }

        bool pop(){
                int     old_head, new_head;
                while(true){
                        old_head = m_head;
                        if(old_head == m_tail) break;
                        new_head = (old_head + 1) % m_data_len;
                        if(__sync_bool_compare_and_swap(&m_head, old_head, new_head)){
                                m_size--;
                                return true;
                        }
                }
                return false;
        }

        size_t size(){
                return m_size;
        }

        bool empty(){
                return m_head == m_tail;
        }

        void output(){
                int head = m_head, tail = m_tail;
                int pos = head;
                cout << "[";
                while(pos != tail){
                        if(pos != head){
                                cout << ",";
                        }
                        cout << m_data[pos];
                        pos = (pos + 1) % m_data_len;
                }
                cout << "]" << endl;
        }

        vector<T> to_vector(){
                vector<T> vec;
                int head = m_head, tail = m_tail;
                int pos = head;
                while(pos != tail){
                        vec.push_back(m_data[pos]);
                        pos = (pos + 1) % m_data_len;
                }
                return vec;
        }

};

}
#endif

测试例程

#include <iostream>
#include "con_queue.hpp"
#include <vector>
#include <thread>
#include <atomic>
#include <algorithm>
#include <queue>

const int per_time = 500000;

const int NUM = 100000;
int que[NUM];

eventsock::ConQueue<int> con_queue(que, NUM);
void test_queue_push(int k){
        for(int i = k * per_time; i < k * per_time + per_time; i++){
                while(true){
                        if(con_queue.push(i)) break;
                        std::this_thread::sleep_for(std::chrono::milliseconds(10));
                };
        }
}
void test_queue_pop(int k){
        for(int i = k * per_time; i < k * per_time + per_time; i++){
                while(true){
                        if(con_queue.pop()) break;
                        std::this_thread::sleep_for(std::chrono::milliseconds(10));
                };
        }
}
void test_con_queue(){
        vector<thread> ths;
        for(int i = 0; i < 10; i++){
                ths.push_back(thread(test_queue_push, i));
        }
        for(int i = 0; i < 10; i++){
                ths.push_back(thread(test_queue_pop, i));
        }
        for(int i = 0; i < ths.size(); i++){
                ths[i].join();
        }
        int num = con_queue.size();
        con_queue.output();
        if(num == 0){
                printf("ConQueue success\n");
        }else{
                printf("EventConnection fail num=%d\n", num);
        }
}
int main(int argc, char* argv[])
{
    test_con_queue();
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值