C ++ Map并发插入和两个线程读取

Sel*_*_va 4 c++ multithreading synchronization dictionary

有两个线程,一个将插入地图,另一个将从地图插入find

map<string,object>* mapA;
Run Code Online (Sandbox Code Playgroud)

如果线程A将配置对象插入带字符串键的Map中。

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

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

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

bas*_*sav 5

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

stl容器的线程安全已在此处讨论:

为什么C ++ STL不提供一组线程安全的容器?

引用规格:

23.2.2容器数据竞赛

“在同时修改容器中除矢量之外的其他元素中所包含对象的内容时,需要采取措施以避免数据争用。”

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

需要锁定的用例:如果您的数据结构间歇性/并发地执行插入和查找,则需要锁定。

不需要锁定的用例:如果您的数据结构一口气被填充,然后随后只进行查找,则不需要锁定。

这是源代码:

STL映射内部使用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;
}
Run Code Online (Sandbox Code Playgroud)

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