基于C++11的阻塞队列简单实现
转载请说明出处:http://blog.csdn.net/cywosp/article/details/9157379
在多线程编程中阻塞队列(Blocking Queue)是一种常用于实现生产者和消费者模型的数据结构。其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)。下图展示如何通过阻塞队列来合作:
接下来我们用C++11来实现一个简单的阻塞队列(没有容量限制的BlockingQueue)
- template<typename T>
- class BlockingQueue
- {
- public:
- BlockingQueue () : _mutex (), _condvar (), _queue ()
- {
-
- }
-
- void Put (const T& task)
- {
- {
- std::lock_guard<std::mutex> lock (_mutex);
- _queue.push_back (task);
- }
- _condvar.notify_all ();
- }
-
- T Take ()
- {
- std::unique_lock<std::mutex> lock (_mutex);
- _condvar.wait (lock, [this]{return !_queue.empty ();});
- assert (!_queue.empty ());
- T front (_queue.front ());
- _queue.pop_front ();
-
- return front;
- }
-
- size_t Size() const
- {
- std::lock_guard<std::mutex> lock (_mutex);
- return _queue.size();
- }
-
- private:
- BlockingQueue (const BlockingQueue& rhs);
- BlockingQueue& operator = (const BlockingQueue& rhs);
-
- private:
- mutable std::mutex _mutex;
- std::condition_variable _condvar;
- std::list<T> _queue;
- };
注:以上代码需要加入下列头文件
#include <condition_variable>
#include <list>
#include <assert.h>
编译时需要加入编译选项 -std=c++0x或者-std=c++11
简单测试程序如下:
将上述代码放到 BlockingQueue.hpp文件中
- #include <iostream>
- #include <thread>
- #include <future>
- #include "BlockingQueue.hpp"
-
- int main (int argc, char* argv[])
- {
- BlockingQueue<int> q;
- auto t1 = std::async (std::launch::async, [&q] () {
- for (int i = 0; i < 10; ++i) {
- q.Put (i);
- }
- });
-
- auto t2 = std::async (std::launch::async, [&q] () {
- while (q.Size ()) {
- std::cout << q.Take () << std::endl;
- }
- });
-
- auto t3 = std::async (std::launch::async, [&q] () {
- while (q.Size ()) {
- std::cout << q.Take () << std::endl;
- }
- });
-
- t1.wait ();
- t2.wait ();
- t3.wait ();
-
- return 0;
- }
编译: g++ -o blockingqueue -std=c++11 main.cpp BlockingQueue.hpp -pthread
执行blockingqueue得如下结果:
本篇文章只是简单的实现了阻塞队列的插入函数与获取函数,在java中有线程的BlockingQueue容器可以直接使用,其提供了很多有用的函数(欲知请Google)。