翻转队列的实现

        在多线程中,经常会出现这样一种模式,A线程向队列L中push元素,B线程从队列L中pop元素,为了线程安全,必须在A push的时候加锁,然后在B pop的时候也加锁,这是一个典型的生产者消费者模式,这样显然会降低程序的效率。那么怎样来优化这种情景呢?

        我们可以使用翻转队列(又称交换队列)来提高这个模型的效率,设计思想是使用2个队列L1,L2,A还是继续向L1中push元素,但是B从L2中pop元素,然后当L2为空的时候,交换L1和L2,这样,A push的时候还是需要加锁,但是B pop的时候就不用加锁,只需要在交换L1和L2的时候加锁,真正产生冲突只有在交换的时候。这样就极大的减少锁互斥的几率,优化了模型的效率。

        代码如下(加锁的代码为伪代码),使用模板实现:        

template<typename _OBJ>
class SwappingList
{
public:
	size_t Add(_OBJ & obj )
	{
		ResGuard<Mutex> lock(m_frontMutex);
		m_frontList->push_back(obj);
		return m_frontList->size();
	}

	bool Get(_OBJ & obj )
	{
		if ( m_backList->empty() )
		{
			Swap();
		}
		if ( m_backList->empty() )
		{
			return false;
		}
		obj = m_backList->front();
		m_backList->pop_front();
		return true;
	}

	void Swap()
	{
		ResGuard<Mutex> lock(m_frontMutex);
		PRODUCT_LIST * p = m_backList;
		m_backList = m_frontList;
		m_frontList = p;
	}

	SwappingList()
	{
		m_frontList = new PRODUCT_LIST;
		m_backList  = new PRODUCT_LIST;
	}

	virtual ~SwappingList()
	{
		if ( m_frontList )
		{
			delete m_frontList;
			m_frontList = 0;
		}
		if ( m_backList )
		{
			delete m_backList;
			m_backList = 0;
		}
	}

protected:
	typedef std::list<_OBJ>   PRODUCT_LIST;
	PRODUCT_LIST*        m_frontList;
	PRODUCT_LIST*        m_backList;
	Mutex                m_frontMutex;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值