2013-09-27 83 views
0

我有多個消費者線程和一個生產者線程。生產者線程將數據寫入屬於某個消費者線程的映射中,並向消費者線程發送信號。當我插入和擦除數據時,我在地圖周圍使用互斥鎖。但是這種方法在速度性能方面看起來效率不高。你可以建議另一種方法,而不是地圖,需要互斥鎖和解鎖,我認爲互斥減慢傳輸。C++多線程緩慢處理

回答

2

但是這種方法在速度性能方面看起來效率不高。你可以建議另一種方法,而不是地圖,需要互斥鎖和解鎖,我認爲互斥減慢傳輸。

您應該使用分析器來確定瓶頸的位置。


生產者線程把數據寫入到地圖屬於某個消費者線程併發送信號給消費者線程。

生產者不應該關心消費者使用什麼樣的數據結構 - 這是消費者的實現細節。請記住,將值插入映射需要內存分配(除非使用自定義分配器),並且內存分配內部也會鎖定以保護堆狀態。最終的結果是鎖定一個互斥量大約在map::insert的操作可能會將其鎖定的時間太長。

一個更簡單和更高效的設計是在生產者和消費者之間有一個原子隊列(例如pipe,TBB concurrent_bounded_queue,它預先分配它的存儲以便推/拉操作非常快)。由於您的生產者直接與每個消費者進行通信,因此該隊列是一個一個讀寫器的閱讀器,並且可以實現爲一個等待隊列(或環形緩衝區a-la C++ disruptor)。

+0

你能推薦一些這些隊列的實現例子嗎?他們在STL或其他地方是標準嗎?你的意思是std :: atomic? –

+0

@AvbAvb我添加了幾個參考。 –

0

Andrei Alexandrescu提出了很好的一點,那就是你應該測量你的代碼(https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920),這與我給你的建議是一樣的,就是測量你的代碼,看看你在基準測試和測試運行單線程:

  1. 使用單線程與上面列出的數據
  2. 插入使用單線程與上面列出的數據映射,並使用互斥 鎖數據 所需的時間映射 插入數據所需的時間

如果你還在尋找一個線程安全的容器,你可能想看看英特爾的開源實施線程安全的容器http://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_queue_cls.htm

而且,對於消費者線程執行的建議,您可能需要閱讀的的activeObject文章認爲香草薩特張貼在他的網站:http://herbsutter.com/2010/07/12/effective-concurrency-prefer-using-active-objects-instead-of-naked-threads/

如果你能提供一些更多的細節,比如爲什麼地圖必須始終鎖定,我們可能能夠起草一個效果更好的機制。