美文网首页
C++实现BlockingQueue

C++实现BlockingQueue

作者: youxiaochen | 来源:发表于2021-08-20 09:45 被阅读0次

BlockingQueue在多线程开发中几乎是离不开的,它可以理解为封装好的生产者与消费者的桥梁,其实它的数据结构同前文讲的Queue一样,只是在此基础之上加入了生产与消费者模式中的wait(阻塞等待,此方法会释放锁)和唤醒(notify)
JDK中提供的常用的BlockingQueue有ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue(优先级)
STL库中queue是链表结构的队列,当然也有提供dequeue(数组结构), priority_queue,这里只写一个用queue来实现的类,其他扩展同理,其实就是一些并发锁的使用

#include <queue>
#include <mutex>

template <class E>
class BlockingQueue {

private:
    queue<E> _queue;
    int capacity = INT_MAX;
    condition_variable takeVariable, putVariable;
    mutable mutex lock;

public:
    BlockingQueue();
    /**
     *
     * @param capacity 队列允许的最大值,在put时size()大于此值时,put方法将会wait
     */
    BlockingQueue(int capacity);
    /**
     * size() == 0 时会阻塞
     * @param e
     * @return -1失败, 0成功
     */
    int take(E &e);
    /**
     * size >= capacity时会阻塞
     * @param e
     * @return
     */
    int put(const E &e);

    bool empty() const;

    unsigned int size() const;

    void pop();

    E back();

    E front();
};

template <class E>
BlockingQueue<E>::BlockingQueue() {
}

template <class E>
BlockingQueue<E>::BlockingQueue(int capacity) : capacity(capacity) {
}

template <class E>
int BlockingQueue<E>::take(E &e) {
    unique_lock<mutex> uniqueLock(lock);
    while (_queue.empty()) {
        takeVariable.wait(uniqueLock);
    }
    if (_queue.empty()) return -1;
    e = _queue.front();
    _queue.pop();
    putVariable.notify_one();
    return 0;
}

template <class E>
int BlockingQueue<E>::put(const E &e) {
    unique_lock<mutex> uniqueLock(lock);
    while (_queue.size() >= capacity) {
        putVariable.wait(uniqueLock);
    }
    if (_queue.size() >= capacity) return -1;
    _queue.push(e);
    takeVariable.notify_one();
    return 0;
}

template <class E>
bool BlockingQueue<E>::empty() const {
    lock_guard<mutex> lockGuard(lock);
    return _queue.empty();
}

template <class E>
unsigned int BlockingQueue<E>::size() const {
    lock_guard<mutex> lockGuard(lock);//利用变量作用域创建加锁,析构自动解锁
    return _queue.size();
}

template <class E>
void BlockingQueue<E>::pop() {
    lock.lock();
    _queue.pop();
    lock.unlock();
}

template <class E>
E BlockingQueue<E>::back() {
    lock_guard<mutex> lockGuard(lock);
    return _queue.back();
}

template <class E>
E BlockingQueue<E>::front() {
    lock_guard<mutex> lockGuard(lock);
    return _queue.front();
}
最后附上源码https://github.com/youxiaochen/DataStructArrayLink

更多文章请关注:http://www.jianshu.com/u/b1cff340957c

相关文章

网友评论

      本文标题:C++实现BlockingQueue

      本文链接:https://www.haomeiwen.com/subject/skwihltx.html