muduo源码解析17-(bounded)blockingqueue类

blockingqueue和boundedblockingqueue

作用:

无边界blockingqueue:

实现了一个有锁的dequeue双端队列
保证put,take,size操作都具有原子性
内部使用互斥锁mutexlock,再使用一个条件变量用于判断队列是否为空

有边界boundedblockingqueue:

实现了一个有边界的双端队列,实现线程安全,对常用的操作加锁,实现原子性
内部使用boost::circular_buffer来存储数据

 

两个类都比较简单

blockingqueue:

/*
实现了一个有锁的dequeue双端队列
保证put,take,size操作都具有原子性
内部使用互斥锁mutexlock,再使用一个条件变量用于判断队列是否为空
*/

#ifndef BLOCKINGQUEUE_H
#define BLOCKINGQUEUE_H

#include"base/condition.h"
#include"base/mutex.h"

#include<deque>
#include<assert.h>

namespace mymuduo
{

template <typename T>
class blockingqueue:noncopyable
{
public:
    blockingqueue():m_mutex(),m_notEmpty(m_mutex),m_queue()
    {

    }

    //队尾添加元素
    void put(const T& x)
    {
        mutexlockguard mlg(m_mutex);
        m_queue.push_back(x);
        m_notEmpty.notify();
    }

    void put(T&& x)
    {
        mutexlockguard mlg(m_mutex);
        //std::move把左值转化成右值引用
        m_queue.push_back(std::move(x));
        m_notEmpty.notify();
    }

    //队头取出元素
    T take()
    {
        mutexlockguard mlg(m_mutex);
        while(m_queue.empty())
            m_notEmpty.wait();
        assert(!m_queue.empty());
        T val=std::move(m_queue.front());
        m_queue.pop_front();
        return val;
    }

    size_t size() const
    {
        mutexlockguard mlg(m_mutex);
        return m_queue.size();
    }

private:
    //mutable修饰的成员变量可以在常成员函数中修改
    mutable mutexlock m_mutex;
    condition m_notEmpty;
    std::deque<T> m_queue;
};


}

#endif // BLOCKINGQUEUE_H

boundedblockingqueue:

/*
实现了一个有边界的队列,实现线程安全,对常用的操作加锁,实现原子性
内部使用boost::circular_buffer来存储数据
*/

#ifndef BOUNDEDBLOCKINGQUEUE_H
#define BOUNDEDBLOCKINGQUEUE_H

#include"base/condition.h"
#include"base/mutex.h"

#include<boost/circular_buffer.hpp>
#include<assert.h>


namespace mymuduo {

template <typename T>
class boundedblockingqueue:noncopyable
{
public:
    explicit boundedblockingqueue(int maxSize)
        :m_mutex(),m_notEmpty(m_mutex),m_notFull(m_mutex),m_queue(maxSize)
    {

    }
    //添加元素
    void put(const T& x)
    {
        mutexlockguard mlg(m_mutex);
        while(m_queue.full())
            m_notFull.wait();
        assert(!m_queue.full());
        m_queue.push_back(x);
        m_notEmpty.notify();
    }

    void put(const T&& x)
    {
        mutexlockguard mlg(m_mutex);
        while(m_queue.full())
            m_notFull.wait();
        assert(!m_queue.full());
        m_queue.push_back(std::move(x));
        m_notEmpty.notify();
    }
    //取出元素
    T take()
    {
        mutexlockguard mlg(m_mutex);
        while(m_queue.empty())
            m_notEmpty.wait();

        assert(!m_queue.empty());
        T val=std::move(m_queue.front());
        m_queue.pop_front();
        m_notFull.notify();
        return val;
    }
    //返回队列各种状态...
    bool empty() const
    {
        mutexlockguard mlg(m_mutex);
        return m_queue.empty();
    }

    bool full() const
    {
        mutexlockguard mlg(m_mutex);
        return m_queue.full();
    }

    size_t size() const
    {
        mutexlockguard mlg(m_mutex);
        return m_queue.size();
    }

    size_t capacity() const
    {
        mutexlockguard mlg(m_mutex);
        return m_queue.capacity();
    }

private:
    mutable mutexlock m_mutex;
    condition m_notEmpty;
    condition m_notFull;
    boost::circular_buffer<T> m_queue;

};


}//namespace mymuduo




#endif // BOUNDEDBLOCKINGQUEUE_H

两个类都比较简单,在常用的操作上加锁实现线程安全,这里不再测试了。

posted @ 2020-08-26 17:56  WoodInEast  阅读(220)  评论(0编辑  收藏  举报