前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >翻转队列的实现

翻转队列的实现

作者头像
帘卷西风
发布2018-08-03 15:52:44
6560
发布2018-08-03 15:52:44
举报

        在多线程中,经常会出现这样一种模式,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的时候加锁,真正产生冲突只有在交换的时候。这样就极大的减少锁互斥的几率,优化了模型的效率。

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

代码语言:javascript
复制
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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013年09月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档