【发布时间】:2013-08-30 10:30:33
【问题描述】:
我有std::map< StudentName, Marks >,其中StudentName 是std::string,Marks 是一个整数。
现在,在我的应用程序中,多个线程正在访问此映射以:
- 找到
StudentName。如果存在,请增加其Marks。 - 将
Marks减少到StudentName。 - 将
StudentName添加到地图中。 - 从地图中删除
StudentName。
问题:在多线程环境中对std::map 进行上述操作最有效的方法是什么?
当前解决方案:
在地图上执行所有这些操作的代码都放在临界区中。但这会降低性能。
(例如,如果一个线程正在为特定学生添加分数,为什么其他要为不同学生添加分数的线程需要等待?)
这是我认为可以做到的:
我从 SO 上的其他类似问题/答案中收集了有关地图上多线程的信息,这就是我认为我需要做的。前提是 std::map 不是线程安全的,(即更新时没有其他线程应该访问映射)
- 我只想将最后两个(添加/删除 StudentName)活动排除在外(在向地图添加/删除元素时,不应并行执行其他活动)
- 不允许多个线程访问同一地图元素(以免多个线程同时尝试增加/减少同一学生的分数)
但我不确定如何实现这一点(可以使用哪些线程同步对象/技术)我正在通过 VS2010 在 Windows 上开发此应用程序
请问这里有什么建议或替代方法吗?
更新: 感谢大家的意见。不幸的是,VS2010 中没有可用的原子整数。所以,这就是我计划根据你的意见做的事情。我将拥有三种锁: 在地图上:map_read_lock、map_write_lock 关于元素:element_write_lock (对于每个元素)
现在,
在地图中查找元素时:获取 map_read_lock (这将允许我同时查找)
在map中添加/删除元素时:获取map_write_lock (这样会阻止容器的并发更新,我认为不推荐)
更改值时:Get (map_read_lock & element_write_lock) (这将允许并行更改不同的值,但会阻止同时更改相同的值。此外,将防止在容器更新时更改值,反之亦然反之)
【问题讨论】:
-
使用互斥锁,即 boost::mutex 和 scope_lock。而最重要的锁只在你必须的时候并且只用了一点时间。例如,当您将元素插入地图并获取值时。就这样。顺便说一句,考虑使用 hashmap,即 std::unordered_map - 在某些情况下更有效。
-
Provided STL map are not thread safe, (i.e. no other thread should access map when it is being updated)不完全是,我已经在这里回答了类似的问题stackoverflow.com/questions/16130494/… 如果您不修改地图本身,则可以访问它的元素以进行读写,只要有给定元素没有竞争条件。 -
@LukeCodeBaker 他需要以某种方式同步他的所有操作。
-
您是如何使用 C++ 实现 map_read_lock、map_write_lock.. 的?几个 std::mutex?
-
@Johy 我用过libuv's thread sync functions。对于读锁uv_rwlock_rdlock and for write uv_rwlock_wrlock,他们在内部使用了相关操作系统的锁定功能,而不是标准,但我不记得了。相当古老的回忆:) 但你可以参考他们的文档。感谢您的提问。
标签: c++ multithreading dictionary std stdmap