我正在std::map< StudentName, Marks >
StudentName
为std::string
且Marks
为整数。
现在,在我的应用程序中,多个线程正在访问此映射到:
StudentName
。如果存在,请增加其Marks
。Marks
的{{1}}。StudentName
添加到地图中。StudentName
。 问题:在多线程环境中对StudentName
执行上述操作的最有效方法是什么?
当前解决方案: 在地图上执行所有这些操作的代码放在关键部分中。但这会降低性能 (例如,如果某个帖子正在为某个学生添加标记,为什么其他想要为不同学生添加标记的帖子需要等待?)
我认为可以做到这一点:
我从SO上的其他类似问题/答案中收集了关于多线程的信息,这是我认为我需要做的事情。如果std::map
不是线程安全的(即,其他线程在更新时不应访问映射)
但我不知道如何实现这一目标(可以使用哪些线程同步对象/技术)我正在通过VS2010在Windows上开发此应用程序
这里有任何建议或替代方法吗?
更新 感谢大家的投入。不幸的是,VS2010中没有原子注入。所以,这是我打算根据你的输入做的。我有三种锁: 在地图上:map_read_lock,map_write_lock 元素:element_write_lock (对于每个元素)
现在,
在地图中查找元素时:获取map_read_lock (这将允许我并发查找)
添加/删除要映射的元素时:获取map_write_lock (这将阻止容器的并发更新,我相信不建议这样做)
更改值时:Get(map_read_lock&amp; element_write_lock)(这将允许并行更改为不同的值,但会阻止并发更改为相同的值。此外,还会阻止在更新容器时更改值反之亦然)
答案 0 :(得分:3)
当一个线程增加标记时会发生什么 学生A,另一个线程删除学生A?你需要 即使只是修改标记,也可以锁定地图。或者您 需要更复杂的事务管理(可能不是 这样一个简单的案例是合理的。)
或者,您可以在地图上使用rwlock,也可以使用独占 锁定地图中的每个元素。要修改标记,请执行 地图上的读锁定以及元素上的独占锁定;至 添加或删除一个学生,你在地图上采取写锁定。但 这需要大量额外资源。
答案 1 :(得分:0)
之后,您可以考虑Reader/Writer lock,其中Reader锁不是独占的。但请注意,因为实际评分是写作,所以你可能需要为每个学生另外锁定以避免争用。
答案 2 :(得分:0)
- 我想只将最后两个(添加/删除StudentName)活动排除在外(在向地图添加/删除元素时,不应该并行执行其他活动)
醇>
为此,您需要在地图上锁定读写器。
- 不允许多个线程访问地图的同一元素(这样多线程不能同时尝试增加/减少同一学生的分数)
醇>
这也是相对简单的:地图的每个元素都应该有自己的锁。这样,当访问元素而不修改地图结构时,您可以:
因此并行访问多个单独的元素。
在Mark
的特定情况下,您还可以查看std::atomic
。当一个简单的atomic
可以做你想做的事情时,无需使用锁定。)