zoukankan      html  css  js  c++  java
  • 翻转队列的实现

            在多线程中,经常会出现这样一种模式,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;
    };
    


  • 相关阅读:
    简单的倒计时 时间显示
    git submodule
    使用选择器语法来查找元素
    yo bootstrap mui 使用对比
    flexbox 兼容安卓4.3
    mac 下 php 安装 中的坑
    微信网页开发
    能发送http请求(get,post)的工具
    h5宣传页制作过程中遇到的问题
    功能模块图、业务流程图、处理流程图、ER图,数据库表图(概念模型和物理模型)画法
  • 原文地址:https://www.cnblogs.com/james1207/p/3310486.html
Copyright © 2011-2022 走看看