赞
踩
传统队列是生产者线程和消费者线程从同一个队列中存取数据,必然需要互斥访问,在互相同步等待中浪费了宝贵的时间,使队列吞吐量受影响。
双缓冲队使用两个队列,将读写分离,一个队列专门用来读,另一个专门用来写,当读队列空或写队列满时将两个队列互换。这里为了保证队列的读写顺序,当读队列为空且写队列不为空时候才允许两个队列互换。
话不多说,上代码
#pragma once #include <deque> #include "mutex.h"//对mutex简单的区域锁封装 namespace util { /* * 多生产者-单消费者队列 */ template<typename T, unsigned Size = 0> class FastQueue { public: FastQueue() : _flag(0) { } ~FastQueue() {} /* * push */ inline void push(const T& elem) { _mutex.lock(); if (_flag == 0) _containerB.push_back(elem); else _containerA.push_back(elem); _mutex.unlock(); } /* * pop */ bool pop(T& elem) { if (_flag == 0) { if (!_containerA.empty()) { elem = _containerA.front(); _containerA.pop_front(); return true; } else { _mutex.lock(); if (!_containerB.empty()) { _flag = 1; _mutex.unlock(); elem = _containerB.front(); _containerB.pop_front(); return true; } _mutex.unlock(); } } else { if (!_containerB.empty()) { elem = _containerB.front(); _containerB.pop_front(); return true; } else { _mutex.lock(); if (!_containerA.empty()) { _flag = 0; _mutex.unlock(); elem = _containerA.front(); _containerA.pop_front(); return true; } _mutex.unlock(); } } return false; } /* * 移除未使用的空间 */ inline void reserved() { _mutex.lock(); _containerA.shrink_to_fit(); _containerB.shrink_to_fit(); _mutex.unlock(); } inline unsigned getSize() { _mutex.lock(); unsigned int size = 0; size = _containerA.size() + _containerB.size(); _mutex.unlock(); return size; } inline unsigned getSizeR() { if (_flag == 0) return (unsigned)_containerA.size(); else return (unsigned)_containerB.size(); } inline unsigned getSizeW() { _mutex.lock(); unsigned int size = 0; if (_flag == 0) size = _containerB.size(); else size = _containerA.size(); _mutex.unlock(); return size; } inline int getFlag(){ return _flag; } private: std::deque<T> _containerA; std::deque<T> _containerB; int _flag; //读线程切换队列状态 Mutex _mutex; }; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。