• C++ 安全队列


    所谓的安全队列,就是封装一个加条件变量和互斥锁的一个队列类,以便在多线程访问该队列资源时是并行操作

    1、多个线程从一个队列中读取数据,加互斥锁和条件变量

    #ifndef SHAREDQUEUE_HPP
    #define SHAREDQUEUE_HPP
    
    #include<iostream>
    #include<memory>
    #include<queue>
    #include<mutex>
    #include<condition_variable>
    
    template <typename T>
    class SharedQueue 
    {
    public:
        SharedQueue();
        ~SharedQueue();
    
        bool pop(std::unique_ptr<T>&& pData);
        void push(std::unique_ptr<T>&& item);
        int size();
        bool empty();
    
    public:
        T operator[] (int k) {
            return m_queue[k];
        }
    private:
        std::deque<std::unique_ptr<T>> m_queue;
        std::mutex m_mutex;
        std::condition_variable m_cond;
    };
    
    template <typename T>
    SharedQueue<T>::SharedQueue(){
    
    }
    
    template <typename T>
    SharedQueue<T>::~SharedQueue(){
    
    }
    
    template <typename T>
    bool SharedQueue<T>::pop(std::unique_ptr<T>&& pData)
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        if (m_queue.empty()) {
            return false;
        }
    
        pData = std::move(m_queue.front());
        m_queue.pop_front();
        return true;
    }
    
    template <typename T>
    void SharedQueue<T>::push(std::unique_ptr<T>&& item)
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        m_queue.push_back(std::move(item));
        mlock.unlock();
        m_cond.notify_all();
    }
    
    template <typename T>
    int SharedQueue<T>::size()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        int size = m_queue.size();
        mlock.unlock();
        return size;
    }
    
    template <typename T>
    bool SharedQueue<T>::empty()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        return m_queue.empty();
    }
    
    #endif

    运行结果:

    Thread idx : 0
    pData : 0
    pData : 1
    pData : 2
    pData : 3
    pData : 4
    pData : 5
    pData : 6
    pData : 7
    pData : 8
    pData : 9
    Thread idx : 1
    Thread idx : 2
    Thread idx : 3

    2、如果多线程安全队列是用在生产者和消费者场景中,即多个生产者(多个线程)往队列里写数据,多个消费者(多个线程)往队列中读数据

    #ifndef SHAREDQUEUE_HPP
    #define SHAREDQUEUE_HPP
    
    #include<iostream>
    #include<memory>
    #include<queue>
    #include<mutex>
    #include<condition_variable>
    
    template <typename T>
    class SharedQueue 
    {
    public:
        SharedQueue();
        ~SharedQueue();
    
        T& front();
        T pop();
        void pop_front();
        void push_back(const T& item);
        void push_back(T&& item);
        void shut_down();
    
        // bool pop(std::unique_ptr<T>&& pData);
        // void push(std::unique_ptr<T>&& item);
        int size();
        bool empty();
        bool is_shutdown();
    
    public:
        T operator[] (int k) {
            return m_queue[k];
        }
    private:
        std::deque<std::unique_ptr<T>> m_queue;
        std::mutex m_mutex;
        std::condition_variable m_cond;
        bool m_bShutDown = false;
    };
    
    // #include"SharedQueue.hpp"
    template <typename T>
    SharedQueue<T>::SharedQueue(){
    
    }
    
    template <typename T>
    SharedQueue<T>::~SharedQueue(){
    
    }
    
    template <typename T>
    bool SharedQueue<T>::is_shutdown() {
        return m_bShutDown;
    }
    
    template <typename T>
    void SharedQueue<T>::shut_down() {
        std::unique_lock<std::mutex> mlock(m_mutex);
        m_queue.clear();
        m_bShutDown = true;
    }
    
    template <typename T>
    T SharedQueue<T>::pop()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        // if (m_queue.empty()) {
        //     return false;
        // }
    
        m_cond.wait(mlock, [this](){return !this.m_queue.empty();});
        T rc(std::move(m_queue.front()));
        m_queue.pop_front();
    
        return rc;
    }
    
    template <typename T>
    T& SharedQueue<T>::front()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        while(m_queue.empty()) {
            m_cond.wait(mlock);
        }    
    
        return m_queue.front();
    }
    
    template <typename T>
    void SharedQueue<T>::pop_front()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        while(m_queue.empty()) {
            m_cond.wait(mlock);
        }
    
        m_queue.pop_front();
    }
    
    template <typename T>
    void SharedQueue<T>::push_back(const T& item)
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        m_queue.push_back(item);
        mlock.unlock();
        m_cond.notify_one();
    }
    
    template <typename T>
    void SharedQueue<T>::push_back(T&& item)
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        m_queue.push_back(std::move(item));
        mlock.unlock();
        m_cond.notify_one();  
    }
    
    template <typename T>
    int SharedQueue<T>::size()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        int size = m_queue.size();
        mlock.unlock();
        return size;
    }
    
    template <typename T>
    bool SharedQueue<T>::empty()
    {
        std::unique_lock<std::mutex> mlock(m_mutex);
        bool is_empty = m_queue.empty();
        mlock.unlock();
        return is_empty;
    }
    
    #endif
  • 相关阅读:
    51nod 1117 聪明的木匠:哈夫曼树
    51nod 1010 只包含因子2 3 5的数
    51nod 2636 卡车加油
    51nod 2989 组合数
    51nod 2652 阶乘0的数量 V2
    51nod 1103 N的倍数
    51nod 2489 小b和灯泡
    51nod 1003 阶乘后面0的数量
    51nod 2122 分解质因数
    javascript中的setter和getter
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/15429578.html
Copyright © 2020-2023  润新知