C++ Map双线程并发插入读取

标签 c++ multithreading dictionary synchronization

有两个线程,一个将插入到 map 中,另一个将从 map 中查找

map<string,object>* mapA;

如果线程 A 将配置对象插入 Map w.r.t 字符串键。

线程 B 将尝试使用相同的字符串键查找的位置。如果不存在,它将重试,直到找到字符串键。

如果线程A在线程B读取key的同时插入,会不会导致进程崩溃或者数据损坏?这里需要同步吗?

在使用示例应用程序进行测试时,我会遇到任何类型的崩溃或损坏

最佳答案

只有当涉及的所有线程都是读取线程时,才可以在没有任何锁定机制的情况下访问容器。

这里讨论了STL容器的线程安全:

Why does the C++ STL not provide a set of thread-safe containers?

引用规范:

23.2.2 容器数据竞争

"implementations are required to avoid data races when the contents of the contained object in different elements in the same container, excepting vector, are modified concurrently."

简而言之,在您的情况下,由于插入和查找都涉及不同的线程,因此需要锁定。

需要锁定的用例: 如果您有一个间歇性/同时执行插入和查找的数据结构,则需要锁定。

不需要锁定的用例: 如果您有一个一次性填充的数据结构,随后只执行查找,则不需要锁定。

这是源代码:

STL map内部使用的是rb-tree,所以这里看一下rb-tree的查找方法。

template <class _Key, class _Value, class _KeyOfValue, 
          class _Compare, class _Alloc>
typename _Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::iterator 
_Rb_tree<_Key,_Value,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k)
{
  _Link_type __y = _M_header;      // Last node which is not less than __k. 
  _Link_type __x = _M_root();      // Current node. 

  while (__x != 0) 
    if (!_M_key_compare(_S_key(__x), __k))
      __y = __x, __x = _S_left(__x);
    else
      __x = _S_right(__x);

  iterator __j = iterator(__y);   
  return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? 
     end() : __j;
}

如上所示,没有使用锁,这是有道理的,因为非线程应用程序并不真正需要/不需要锁的开销。

关于C++ Map双线程并发插入读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32815753/

相关文章:

java - 使用不同的线程迭代 ConcurrentSkipListSet 删除元素

c# - 如何在不阻塞主线程的情况下将 Thread.Sleep 与 Task.Run 一起使用

c++ - 找到绘制的线的交点

c++ - 运行时错误 : load of value 127, 这不是类型 'bool' 的有效值

c++ - 使用 pthread 同时 push() 到共享队列?

c++ - TIM6,基本时间生成功能不起作用

multithreading - 虚拟CPU的含义是什么?

ios - 删除字典中的特定重复项

arrays - 如何使用映射分配结构类型值?

Python 输入 : Retrieve required keys from TypedDict definition