传统队列是生产者线程和消费者线程从同一个队列中存取数据,必然需要互斥访问,在互相同步等待中浪费了宝贵的时间,使队列吞吐量受影响。
双缓冲队使用两个队列,将读写分离,一个队列专门用来读,另一个专门用来写,当读队列空或写队列满时将两个队列互换。这里为了保证队列的读写顺序,当读队列为空且写队列不为空时候才允许两个队列互换。
话不多说,上代码
#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;
};
}