std::map的高效线程同步技术
Efficient thread synchronization technique for std::map
我有std::map< StudentName, Marks >
,其中StudentName
是std::string
,Marks
是整数。
现在,在我的应用程序中,多个线程正在访问这个映射到:
- 查找
StudentName
。如果存在,则增加其Marks
- 降低
StudentName
的Marks
- 将
StudentName
添加到地图中 - 从地图中删除
StudentName
问题:在多线程环境中,对std::map
执行上述操作最有效的方法是什么?
当前解决方案:在地图上执行所有这些操作的代码都放在关键部分中。但这会降低性能
(例如,如果一个线程正在为特定学生添加分数,为什么其他想要为不同学生添加分数的线程需要等待?)
我认为这是可以做到的:
我从SO上的其他类似问题/答案中收集了关于映射上多线程的信息,以下是我认为我需要做的。假设std::map
不是线程安全的(即,当映射更新时,没有其他线程应该访问它)
- 我只想将最后两个(添加/删除StudentName)活动排除在外(在映射中添加/删除元素时,不应并行执行其他活动)
- 不允许多个线程访问映射的同一元素(这样多个线程就不能同时尝试增加/减少同一学生的分数)
但我不确定如何实现这一点(可以使用哪些线程同步对象/技术)我正在通过VS2010在Windows上开发此应用程序
这里有什么建议或替代方法吗?
更新:感谢大家的投入。遗憾的是,VS2010中没有可用的原子int。因此,以下是我根据您的意见计划做的事情。我要三种锁:在地图上:map_read_lock、map_write_lock关于元素:element_write_lock(对于每个元素)
现在,
在地图中查找元素时:获取map_read_lock(这将允许我同时查找)
当向映射添加/删除元素时:Get-map_write_lock(这将阻止容器的并发更新,我认为这是不推荐的)
更改值时:Get(map_read_lock&element_write_lock)(这将允许对不同值进行并行更改,但将防止对同一值进行并发更改。此外,在更新容器时将防止对值进行更改,反之亦然)
当一个线程增加学生A,另一个线程删除学生A?你需要即使只是在修改标记时也能锁定地图。或者你需要更复杂的事务管理(可能不是对于这样一个简单的案例来说是合理的)。
或者,您可以在地图上使用rwlock锁定地图中的每个元素。要修改标记,您需要映射上的读取锁定和元素上的排他锁定;到添加或删除一个学生,你就可以在地图上进行写锁定。但是这需要大量的额外资源。
- 第一个问题:给学生打分的效率应该有多高
- 第二个问题:真的需要多线程吗?如果这是为了效率,也许甚至于事无补
之后,您可以考虑Reader/Writer锁,其中Reader锁不是独占的。但要注意,因为实际的评分是书面的,所以你可能需要为每个学生另加一个锁来避免争论。
- 我只想将最后两个(添加/删除StudentName)活动排除在外(在映射中添加/删除元素时,不应并行执行其他活动)
为此,您需要在地图上锁定读写器。
- 添加/删除需要独占访问(写入程序)
- 访问学生需要(仅)共享访问(阅读器)
- 不允许多个线程访问映射的同一元素(这样多个线程就不能同时尝试增加/减少同一学生的分数)
这也相对简单:映射的每个元素都应该有自己的锁。这样,当访问元素而不修改映射结构时,您只需:
- 在共享访问中锁定地图
- 锁定单个元素(即每个元素都需要自己的锁)
从而并行地访问多个单独的元件。
在Mark
的特殊情况下,您也可以查看std::atomic
。当一个简单的atomic
可以做你想做的事情时,不需要使用锁:)
- 松弛原子与无同步情况下的记忆连贯性
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在C++中同步线程
- 与 stdio 同步是否使程序 I/O 非交互式?
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- C++ 关于指针取消引用的技术问题
- 如何在qt中同步应用程序和显示器的刷新率?
- Windows 进程间同步类似事件?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- 将 10 个线程与原子布尔值同步
- 如何在 SEAL 3.1 中使用 CRT 批处理技术Microsoft?
- ofstream::close() 是否在 Linux 上调用同步?
- 与Visual Studios(c ++)同步时如何组织github存储库?
- 暴力破解技术解决以下问题
- 原子获取是否与互斥锁释放同步?
- Boost (Beast) websocket:同步写入挂起
- std::map的高效线程同步技术
- 进程同步技术