• 翻转队列的实现


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


  • 相关阅读:
    《人件》阅读笔记五
    《人件》阅读笔记四
    《人件》阅读笔记三
    《人件》阅读笔记二
    《人件》阅读笔记一
    年报系统课堂讨论记录
    系统利益相关者描述案例
    Android开发学习记录--活动生命周期
    jQuery AJAX简介
    jQuery HTML简介
  • 原文地址:https://www.cnblogs.com/james1207/p/3310486.html
Copyright © 2020-2023  润新知