【问题标题】:C++ Map Concurrent Insertion and Reading by Two threadsC++ Map 两个线程并发插入和读取
【发布时间】:2015-12-25 06:25:48
【问题描述】:

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

map<string,object>* mapA;

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

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

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

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

【问题讨论】:

    标签: c++ multithreading dictionary synchronization


    【解决方案1】:

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

    这里已经讨论了stl容器的线程安全:

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

    引用规范:

    23.2.2 容器数据竞争

    " 需要实现以避免数据竞争 同一容器中不同元素中包含的对象, 除了向量,同时修改。”

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

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

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

    这里是源代码:

    STL map内部使用了rb-tree。所以,这里看一下rb-tree find方法。

    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;
    }
    

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

    【讨论】:

    • 是否需要同步来查找关键元素是否在容器中?
    • 尚不清楚.. U 说得像 简而言之,在您的情况下,由于 insert 和 find 都涉及到不同的线程,因此需要锁定。 和下一行 u告诉相反的情况是不需要锁定..所以在我的情况下,线程 A 将插入一个密钥,同时该密钥被循环中的另一个线程(线程 B)搜索(仅搜索)..是否需要锁?
    • 不要使用互斥锁或临界区。我可以使用 atomic_bool 并进行手动同步吗?
    • 期待这篇文章的解决方案stackoverflow.com/questions/32839569/…
    【解决方案2】:

    基本上你不知道会发生什么,STL 不会承诺数据将准备好从第一个线程读取,而另一个线程执行插入操作。如果你想这样做,你需要锁定,仅仅因为你没有看到任何问题并不意味着它永远不会发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-10
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      相关资源
      最近更新 更多