在多線程中,經常會出現這樣一種模式,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; };