一个动态扩容的无锁队列实现

先记录一下 目前看起来还有很大优化空间

spsc

不支持深拷贝

#ifndef FAC_PLATFORMNEW_FIXEDQUEUE_H
#define FAC_PLATFORMNEW_FIXEDQUEUE_H
#include <iostream>
#include <vector>
#include <atomic>
#include <chrono>
#include <thread>
#include <string.h>

template<typename T>
class FixedQueue {
public:
    explicit FixedQueue(size_t capacity) : capacity_(capacity), queue_(capacity) {}
    FixedQueue(const FixedQueue&) = delete;
    ~FixedQueue() { clear(); }

    bool Enqueue(T item) {
        size_t currentTail = write_.load(std::memory_order_relaxed);
        size_t nextTail = (currentTail + 1) % capacity_;

        while(nextTail == read_.load(std::memory_order_acquire)) {
            if (is_full()) {
                // Queue is full, resize the queue
                size_t newCapacity = capacity_ * 2;
                std::vector<T> newQueue(newCapacity);

                // Copy existing elements to the new queue
//                for (size_t i = 0; i < capacity_; ++i) {
//                    newQueue[i] = queue_[(nextTail + i) % capacity_];
//                }
                // 第一段memcpy:复制从nextTail开始到队列末尾的元素
                size_t elementsToEnd = capacity_ - nextTail;
                if(elementsToEnd!=0) memcpy(newQueue.data(), &queue_[nextTail], elementsToEnd * sizeof(T));
                // 第二段memcpy:复制从队列开头到nextTail之前的元素
                if(currentTail != 0) memcpy(newQueue.data() + elementsToEnd, queue_.data(), currentTail  * sizeof(T));
                //fake copy cost time
                std::cout << "Queue is full:" << nextTail << "capacity: " << capacity_ << ", resized to new capacity: " << newCapacity << std::endl;
//                std::this_thread::sleep_for(std::chrono::milliseconds(100));
                // Update head and tail indices
//                std::cout << read_.load() << std::endl;
                int cr = read_.load(std::memory_order_acquire);
                read_.store((cr - nextTail + capacity_) % capacity_, std::memory_order_release);
                currentTail = capacity_-1;
                nextTail = capacity_;
                // Replace the existing queue with the new queue
                queue_ = std::move(newQueue);
                capacity_ = newCapacity;
            }
        }
//        std::cout << "set value and write ptr ++ ct: " << currentTail<< std::endl;
        queue_[currentTail] = item;
        write_.store(nextTail, std::memory_order_release);
        return true;
    }

    T Dequeue() {
        size_t currentHead = read_.load(std::memory_order_acquire);
//        std::cout << " Dequeue currenthead: " << currentHead << std::endl;
        while(currentHead == write_.load(std::memory_order_acquire)) {
            std::cout << "queue is empty, unable to dequeue item" << std::endl;
//            std::this_thread::sleep_for(std::chrono::milliseconds(20));
            size_t currentHead = read_.load(std::memory_order_acquire);
        }

        T item = queue_[currentHead]; // 清空已出队的元素
//        std::cout << "Dequeue item index: " << currentHead;
        read_.store((currentHead + 1) % capacity_, std::memory_order_release);
        return item;
    }

    bool is_full() const {
        size_t currentTail = write_.load(std::memory_order_relaxed);
        size_t nextTail = (currentTail + 1) % capacity_;
        return nextTail == read_.load(std::memory_order_acquire);
    }

    bool is_empty() const {
        return read_.load(std::memory_order_acquire) == write_.load(std::memory_order_acquire);
    }


    void clear() {
        read_.store(0, std::memory_order_relaxed);
        write_.store(0, std::memory_order_relaxed);
    }

private:
    size_t capacity_;
    std::atomic<size_t> read_{0};
    std::atomic<size_t> write_{0};
    std::vector<T> queue_;
};

#endif //FAC_PLATFORMNEW_FIXEDQUEUE_H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值