C++11 实现简单的阻塞队列

一个blocking queue是一个支持 take 和 put 的 queue。

take操作从队列中取出一个元素,如果队列为空,那么take会阻塞到直到队列中有可用元素。

put操作往队列里放入一个元素,如果队列是满,那么put会阻塞到队列有可用空间。

一个简单的blocking queue的实现,首先我们要有一个非常底层的容器,至于是vector还是deque甚至是list都无所谓,我们这里选择deque作为容器

前面定义的blocking queue是有界的,也就是说元素有上限,所以才会出现满元素阻塞的情况。

我们先从简单的无界阻塞队列开始,默认这个队列可以一直存储元素。于是我们就不用去判断队列满元素的情况了。这个时候我们只需要一个条件变量来判断队列为空并且阻塞就行。大概框架如下。

 

template<typename T>
class BlockQueue{
    std::deque<T> que;
    std::condition_variable empty;
    std::mutex mtx; // declared for unique_lock;
public:
    T take();
    void put(T elem);
    int size();
}

那么核心的take和put要怎么实现呢?

首先修改队列的操作要加锁,并发编程的时候只要涉及到修改可变变量都必须要加锁,不巧put和take都是在修改队列

这里使用unique_lock来加锁

 

std::unique_lock<std::mutex> lock{mtx};

两个操作中只有take操作会出现队列为空的情况,所以take必须判断队列为空,这里使用条件变量

 

empty.wait(lock, [this]{return !que.empty();});

于是我们的put和take操作就出来了

 

template<typename T>
T BlockQueue::take(){
     std::unique_lock<std::mutex> lock{mtx};
     empty.wait(lock, [this]{return !que.empty();});
     auto res = que.front():
     que.pop_front():
     return res;
}

template<typename T>
void BlockQueue::put(T elem){
     std::unique_lock<std::mutex> lock{mtx};
     que.push_back(T elem);
}



作者:不动点P
链接:https://www.jianshu.com/p/9dd1b7863667
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值