欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

通过c++11的condition_variable实现的有最大缓存限制的队列

程序员文章站 2022-05-17 16:14:36
通过condition_variable实现的有最大长度限制的队列: 由于需要控制队列的长度, 所以没有使用二级缓存, 也就是说, 没有在消费线程使用std::vector之类的进行二级缓存, 使用二级缓存需要考虑均匀分布的问题. 当然, 就算使用二级缓存, 也可以控制待处理的数据的长度, 但是处理 ......

通过condition_variable实现的有最大长度限制的队列:

#include <condition_variable>
#include <queue>
#include <chrono>
#include <iostream>

/*
 * 有最大队列个数限制
 */

// 参数t需要能够拷贝,而且拷贝不会存在副作用
template <typename t>
class sync_queue {
public:
    sync_queue(int queuemaxsize): m_queuemaxsize(queuemaxsize) { }

    // 处理数据线程
    template <typename func>
    typename std::result_of<func(t)>::type readqueue(func readfunc) {
        t data;
        // 取出数据, 然后处理数据
        {
            std::unique_lock<std::mutex> lock(m_queuemtx);
            m_consumecv.wait(lock, [this]{ return m_data.size() != 0; });

            data = m_data.front();
            m_data.pop();
        }
        m_producecv.notify_one();

        return readfunc(data);
    }

    // 生产数据线程, 返回值表示是否生产成功,如果超时就不会生产成功
    template <typename rep, typename period>
    bool writequeue(t data, const std::chrono::duration<rep, period>& wait_time) {
        // 预设一个消费者处理这个数据
        {
            std::unique_lock<std::mutex> lock(m_queuemtx);
            auto success = m_producecv.wait_for(lock, wait_time, [this]{ return m_data.size() <= m_queuemaxsize; });
            if (!success) {
                return false;
            }
            m_data.push(std::move(data));
        }
        m_consumecv.notify_one();
        return true;
    }

private:
    // 用来存储生产者存储的值
    std::queue<t> m_data;
    // 用来表示待处理的数据
    int m_queuemaxsize;
    // 用来队列保护
    std::mutex m_queuemtx;
    // 用来提醒当前可以消费
    std::condition_variable m_consumecv;
    // 用来提醒当前可以生产
    std::condition_variable m_producecv;
};

由于需要控制队列的长度, 所以没有使用二级缓存, 也就是说, 没有在消费线程使用std::vector之类的进行二级缓存, 使用二级缓存需要考虑均匀分布的问题. 当然, 就算使用二级缓存, 也可以控制待处理的数据的长度, 但是处理会变得很复杂. 这里只是提供一个简单的用法, 需要其他效果的, 可以参考构建.