• 细粒度锁的极简单线程安全队列


    template<typename T>
    class ThreadsafeQueue
    {
    private:
        struct Node
        {
            std::shared_ptr<T>       data;
            std::unique_ptr<T>       next;
        };
    
        std::unique_ptr<Node>        head;
        Node*                        tail;
        mutable std::mutex           headMutex;
        mutable std::mutex           tailMutex;
        std::condition_variable      dataCond;
    
        Node* getTail () const
        {
            std::lock_guard<std::mutex> lock(tailMutex);
            return tail;
        }
    
        std::unique_lock<std::mutex> waitForData();
    
        std::unique_ptr<Node> popHead ()
        {
            std::lock_guard<std::mutex> lock(headMutex);
            auto oldHead = std::move(head);
            head = std::move(oldHead->next);
            return oldHead;
        }
    
        std::unique_ptr<Node> waitPopHead ()
        {
            std::unique_lock<std::mutex> lock(waitForData ());
            return popHead ();
        }
    
        std::unique_ptr<Node> waitPopHead (T& popedValue)
        {
            std::unique_lock<std::mutex> lock(waitForData ());
            popedValue = std::move(*head->data);
            return popHead ();
        }
    
        std::unique_ptr<Node> tryPopHead ()
        {
            std::lock_guard<std::mutex> lock(headMutex);
            if (head.get () == getTail ()){
                return std::unique_ptr<Node>();
            }
            return popHead ();
        }
    
        std::unique_ptr<Node> tryPopHead (T& popedValue)
        {
            std::lock_guard<std::mutex> lock(headMutex);
            if (head.get () == getTail ()){
                return std::unique_ptr<Node>();
            }
            popedValue = std::move(*head->data);
            return popHead ();
        }
    
    public:
        ThreadsafeQueue():
            head(std::make_shared<T>()), tail(head.get ())
        {}
    
        ThreadsafeQueue(const ThreadsafeQueue&)            = delete;
        ThreadsafeQueue& operator=(const ThreadsafeQueue&) = delete;
    
        std::shared_ptr<T>           tryPop();
        bool                         tryPop(T&);
        std::shared_ptr<T>           waitAndPop();
        void                         waitAndPop(T& value);
        void                         push(T newValue);
        bool                         empty();
    };
    
    template<typename T>
    void ThreadsafeQueue<T>::push (T newValue)
    {
        auto const newData = std::make_shared<T>(std::move(newValue));
        auto       newNext = std::make_unique<Node>();
        auto       newTail = newNext.get();
        std::lock_guard<std::mutex> lock(tailMutex);
        tail->next = std::move(newNext);
        tail->data = newData;
        tail = newTail;
        dataCond.notify_one ();
    }
    
    template<typename T>
    inline std::unique_lock<std::mutex> ThreadsafeQueue<T>::waitForData ()
    {
        std::unique_lock<std::mutex> lock(headMutex);
        dataCond.wait(lock, [&]{return head != getTail ();});
        return std::move(lock);
    }
    
    template<typename T>
    inline bool ThreadsafeQueue<T>::empty ()
    {
        std::lock_guard<std::mutex> lock(headMutex);
        return (head.get () == getTail ());
    }
    
    template<typename T>
    inline std::shared_ptr<T> ThreadsafeQueue<T>::waitAndPop ()
    {
        auto const oldHead = waitPopHead ();
        return oldHead->data;
    }
    
     template<typename T>
    inline void ThreadsafeQueue<T>::waitAndPop (T& popedValue)
    {
        waitPopHead (popedValue);
    }
    
    template<typename T>
    inline std::shared_ptr<T> ThreadsafeQueue<T>::tryPop ()
    {
        auto const oldHead = tryPopHead();
        return oldHead? oldHead->data : std::shared_ptr<T>();
    }
    
    template<typename T>
    inline bool ThreadsafeQueue<T>::tryPop (T& popedValue)
    {
        auto const oldHead = tryPopHead (popedValue);
        return oldHead;
    }
     
  • 相关阅读:
    hadoop安装前的准备
    记录一次Qt5程序无法运行的解决过程
    C#里的Thread.Join与Control.Invoke死锁情况
    qbxt7月笔记
    zhxのDP讲
    有n*m的方格图
    最长上升子序列相关问题笔记
    qbxt游记(清北澡堂划水记
    DAZの七下道法(持续更新
    模板
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4840039.html
Copyright © 2020-2023  润新知