C++ 线程安全队列

/******************************************************************************
*
* @file       ts_deque.h
* @author     Wei Wang -> shaxikai@outlook.com
* @date       2025.6.13
* @version    V1.0.0"
* @brief      thread safe deque
*
*****************************************************************************/



#pragma once

#include <deque>
#include <mutex>
#include <condition_variable>
#include <utility>
#include <stdexcept>

template<typename T>
class TSDeque {
public:
    TSDeque() = default;
    ~TSDeque() = default;

    TSDeque(const TSDeque&) = delete;
    TSDeque& operator=(const TSDeque&) = delete;

    void push_back(const T& item) {
        std::lock_guard<std::mutex> lock(mutex_);
        deque_.push_back(item);
        cond_.notify_one();
    }

    void push_back(T&& item) {
        std::lock_guard<std::mutex> lock(mutex_);
        deque_.push_back(std::move(item));
        cond_.notify_one();
    }

    void push_front(const T& item) {
        std::lock_guard<std::mutex> lock(mutex_);
        deque_.push_front(item);
        cond_.notify_one();
    }

    void push_front(T&& item) {
        std::lock_guard<std::mutex> lock(mutex_);
        deque_.push_front(std::move(item));
        cond_.notify_one();
    }

    bool pop_front(T& item) {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_.wait(lock, [this]() { return !deque_.empty() || stopped_; });

        if (stopped_ && deque_.empty())
            return false;

        item = std::move(deque_.front());
        deque_.pop_front();
        return true;
    }

    bool pop_back(T& item) {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_.wait(lock, [this]() { return !deque_.empty() || stopped_; });

        if (stopped_ && deque_.empty())
            return false;

        item = std::move(deque_.back());
        deque_.pop_back();
        return true;
    }

    bool pop_front() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (deque_.empty() || stopped_)
            return false;
        deque_.pop_front();
        return true;
    }

    bool pop_back() {
        std::lock_guard<std::mutex> lock(mutex_);
        if (deque_.empty() || stopped_)
            return false;
        deque_.pop_back();
        return true;
    }

    void stop() {
        std::lock_guard<std::mutex> lock(mutex_);
        stopped_ = true;
        cond_.notify_all();
    }

    bool empty() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.empty();
    }

    size_t size() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.size();
    }

    T& front() {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.front();
    }

    const T& front() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.front();
    }

    T& back() {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.back();
    }

    const T& back() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.back();
    }

    T& operator[](size_t index) {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.at(index);
    }

    const T& operator[](size_t index) const {
        std::lock_guard<std::mutex> lock(mutex_);
        return deque_.at(index);
    }

    bool wait_for_data() {
        std::unique_lock<std::mutex> lock(mutex_);
        cond_.wait(lock, [this]() { return !deque_.empty() || stopped_; });
        return !deque_.empty();
    }

private:
    mutable std::mutex mutex_;
    std::condition_variable cond_;
    std::deque<T> deque_;
    bool stopped_ = false;
};
posted @ 2025-07-09 11:32  narjaja  阅读(22)  评论(0)    收藏  举报