2013-02-27 75 views
1

环境:WINDOWS 7.0,C++,多线程多线程与多重映射

我创建了一个新的工作线程接收插座上的数据,并将其添加到一个静态multimap实例。

代码片段:

//remember mymultimap is static data type 
static std::multimap<string,string> mymultimap; 
EnterCriticalSection(&m_criticalsection); 
mymultimap.insert ("aaa", "bbb")); 
LeaveCriticalSection(&m_criticalsection); 

在同一时间我的主线程读取相同的静态多重映射: 代码卡:

EnterCriticalSection(&m_criticalsection); 
std::multimap<string,string>::iterator it = mymultimap.begin(); 
for(; it != mymultimap.end(); it++) 
{ 
std::string firstName = (*it).first; 
std::string secondName = (*it).second; 
} 
LeaveCriticalSection(&m_criticalsection); 

作为主要工作线程汽车无做读写,它妨碍了我的应用程序性能。 multimap的实例还包含大量数据(超过10,000条记录)。

如何在multimap中使线程锁定时间最短?

EnterCriticalSection(&m_criticalsection); 
///minimal lock time for Map ??? 
LeaveCriticalSection(&m_criticalsection); 

请帮我提高我的应用程序性能。

+1

根据您在循环中执行的操作,您可以将数据复制到第二个集合,然后在离开临界区之后对副本执行(可能)冗长的操作。 – 2013-02-27 13:10:35

回答

1

因为它的问题留下了太多的讨论空间:我们不知道如何实际使用multimap中存储的值。

如果:

  • 在数据结构实施的顺序很重要,
  • 你需要保持在多重映射值,他们已经阅读后,也
  • 你需要去通过所有每次你读的条目,

那么你几乎坚持如何优化使用该结构。另一方面,如果您可以以某种方式放松其中一项要求,那么您可能会优化一些东西,例如通过使用消息队列而不是直接用于两个线程之间的通信。

消息队列是实现线程间高效通信的标准方式,对于一对一安装,甚至有无锁解决方案。

更新:考虑一下,在线程中共享这种类型的结构并不是一个好主意,不管你使用它。最好在单个线程中重新组合所有对multimap的访问,并将其他线程生成的项传递给通过队列管理它的线程。这完全分离了从存储和使用中生成物品的工作。在你的情况下,生产者线程将丢失更少的时间存储数据,这使得处理套接字流更多的时间。

因此,对于该解决方案,您需要(例如std::queue),以便在初始化时处理这两个线程,或者像multimap那样处理静态实例。然后,简单地将第一个线程中的multimap::insert替换为make_pair(key, value)queue::push_back,并在消费者线程中对称地更新队列中的所有挂起对,并将它们同时插入到映射中,然后执行处理你的地图,不管它是什么。

注:

请注意,如果您使用的是多重映射,你可能最终得到了相同的密钥多个值:调用find将返回一个迭代器,你很可能要检查multimap的下一个条目,以确保您获得具有相同键的所有值。

+0

在主线程循环中,我读取特定键的MultiMap的值。我可以这样做主线程吗? EnterCriticalSection(&m_criticalsection); std :: multimap :: iterator it = mymultimap.begin(); LeaveCriticalSection(&m_criticalsection); – sandy 2013-02-27 13:24:45

+2

@sandy如果你只需要一个特定的键,为什么不使用'multimap :: find'?迭代器不会因插入而失效。 – pmr 2013-02-27 13:31:54

+0

感谢您的建议。我已经使用队列来解决问题。 – sandy 2013-02-28 15:06:21