安全线程队列(二)

来源:互联网 发布:小猪软件下载 编辑:程序博客网 时间:2024/06/10 23:59

在之前的基础上增加了条件变量,相比之前的等待时间减少,

处理速度更快


/**
* @brief CThreadSafeQueue 基于锁和条件变量的线程安全栈
* @brief 相对来说比上面设计上不需要过多的加锁等待,速度要更快
*/
template<typename T>
class CCondSafeQueue : public CThreadSafeQueue<T>
{
private:
    /**
    * @brief mut 线程安全锁变量
    */
    mutable std::mutex mut;

    /**
    * @brief data_queue 储存数据队列
    */
    std::queue<T> data_queue;

    /**
    * @brief data_queue 条件变量
    */
    std::condition_variable data_cond;

public:
    CCondSafeQueue(){}

    /**
    * @brief 复制构造函数
    */
    CCondSafeQueue(const CCondSafeQueue& other);

    /**
    * @brief push 入队列加锁保护
    */
    virtual void push(T new_value);

    /**
    * @brief 出队列加锁保护, 返回计数指针防止泄露
    */
    virtual void pop(T& value); // 2

    /**
    * @brief 出队列加锁保护, 返回引用,返回方式与上述有所不同
    */
    virtual std::shared_ptr<T> pop(); // 3

    /**
    * @brief 队列是否为空
    */
    virtual bool empty();

};

template<typename T>
CCondSafeQueue<T>::CCondSafeQueue(const CCondSafeQueue& other)
{
    std::lock_guard<mutex> lock(other.m);
    data = other.data;
}

template<typename T>
void CCondSafeQueue<T>::push(T new_value)
{
    std::lock_guard<std::mutex> lk(mut);
    data_queue.push(std::move(new_value));
    data_cond.notify_one(); // 1
}

template<typename T>
void CCondSafeQueue<T>::pop(T& value) // 2
{
    std::unique_lock<std::mutex> lk(mut);
    data_cond.wait(lk, [this] {return !data_queue.empty(); });
    value = std::move(data_queue.front());
    data_queue.pop();
}

template<typename T>
std::shared_ptr<T> CCondSafeQueue<T>::pop() // 3
{
    std::unique_lock<std::mutex> lk(mut);
    data_cond.wait(lk, [this] {return !data_queue.empty(); }); // 4

    std::shared_ptr<T> res(
        std::make_shared<T>(std::move(data_queue.front())));
    data_queue.pop();
    return res;
}

template<typename T>
bool CCondSafeQueue<T>::empty()
{
    std::lock_guard<mutex> lock(mut);
    return data_queue.empty();
}
原创粉丝点击