C++11 implements a simple blocking queue

A blocking queue is a queue that supports take and put.

The take operation takes an element from the queue. If the queue is empty, then take will block until there are available elements in the queue.

The put operation puts an element into the queue. If the queue is full, the put will block until the queue has free space.

To implement a simple blocking queue, we must first have a very low-level container. As for vector, deque or even list, it doesn't matter. We choose deque as the container here.

The blocking queue defined earlier is bounded, that is to say, the element has an upper limit, so there will be full element blocking.

Let's start with a simple unbounded blocking queue, which can store elements all the time by default. So we don't have to judge whether the queue is full of elements. At this time, we only need a condition variable to determine that the queue is empty and blocked. The approximate framework is as follows.

 

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();
}

So how to realize the core take and put?

First of all, the operation of modifying the queue must be locked. When concurrent programming involves modifying variable variables, it must be locked. Unfortunately, both put and take are modifying the queue.

Here use unique_lock to lock

 

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

Of the two operations, only the take operation will cause the queue to be empty, so take must determine that the queue is empty, and condition variables are used here

 

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

So our put and take operations came out

 

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);
}



Author: fixed point P
link: https: //www.jianshu.com/p/9dd1b7863667
Source: Jane books
are copyrighted by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

Guess you like

Origin blog.csdn.net/qingzhuyuxian/article/details/108463637