我希望能够从多个线程读取和写入std :: map。有没有办法在没有互斥量的情况下做到这一点(可能使用std :: atomic)?
如果没有,在C ++ 11中最简单的方法是什么?
答案 0 :(得分:7)
如果值是std::atomic<>
,您可以从任意线程修改并读取它们,但您需要以某种方式保存其地址 - 指针,引用或迭代器 - 你需要知道没有其他线程会在它们上面调用erase
....
尽管如此,即使是原子值也不会使修改容器(例如插入或擦除元素)变得安全,而其他线程也在进行修改,查找或迭代。即使是“const
”函数(如size()
,empty()
,begin()
,end()
,count()
和迭代器运动 - 也是不安全的,因为变异操作可能正在重新连接节点间链接或更新相同的数据。
除上述内容外, 需要互斥锁。
对于一个具体示例,假设您已插入一个带有std::string
键"client_counter"
的节点 - 您可以启动一个线程,该线程获取该元素的迭代器并对计数器进行原子更新,而其他线程可以find
元素并从中读取,但不能erase
它。您仍然可以在map
中插入其他节点以及其他更新程序和阅读器,而无需与client_counter
- 更新线程进行任何额外同步。
答案 1 :(得分:1)
如果您不想使用互斥锁,那么您需要等待并发容器(C ++ 17?)。如果您想在std::atomic
内使用std::map
操作,那么您可能希望在Internet上创建或找到并发原子std::map
的完全实现。
如果您想使用std::map
std::atomic
,那么您可能需要知道这只会保护std::map
内的元素,而不会保护std::map
中的元素。