2015-09-28 48 views
2

有兩個線程,其中一個將插入到地圖中和從地圖另一個將findC++地圖併發插入和讀出由兩個線程

map<string,object>* mapA; 

如果線程A將配置對象插入到映射w.r.t中的字符串鍵。

當線程B將嘗試找到具有相同字符串鍵。如果不存在,它會再次嘗試,直到找到字符串鍵。

它會導致在此過程中崩潰或數據損壞,如果在同一時間線程A插入當線程B讀取密鑰?這裏需要同步嗎?

當用一個示例應用程序測試我不力面對任何類型崩潰或腐敗

回答

3

的容器的可在沒有任何鎖定機構被訪問,只有在所涉及的所有線程都讀取器線程。

STL容器的線程安全性已經在這裏討論:

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

引述規格:

「實現都必須避免

23.2.2集裝箱數據爭

數據競賽時 的內容包含在同一容器中的不同元素中, 除矢量外,都是同時修改的。「

總之,在你的情況下,由於插入和查找都涉及不同的線程,所以需要鎖定。

需要鎖定的用例: 如果您有一個數據結構間歇/同時執行插入和查找操作,則需要鎖定。

在不需要鎖定用例: 如果您有在一杆填充,隨後,只執行的發現則鎖定不需要數據結構。

這裏是源代碼:

STL地圖使用RB樹internally.so,這裏一看就是RB-樹查找方法。

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

如所看到的,沒有鎖定使用,並且它是有道理的,因爲是不是真的需要/期望用於非線程應用鎖定的開銷。

+0

需要同步才能找到密鑰元素是否存在於容器中? –

+0

還不清楚..你說的是_簡而言之,在你的情況下,因爲插入和查找都涉及不同的線程,所以需要鎖定._和下一行你告訴相反的事情,不需要鎖定。所以在我的情況下,線程A將插入一個鍵,同時該鍵被循環中的另一個線程(線程B)搜索(**只搜索**)。鎖是否需要? –

+0

而不是去互斥或臨界區..我可以使用atomic_bool並做手動同步? –

0

基本上,你不知道會發生什麼,STL將不作任何承諾,該數據將隨時爲您從第一個線程讀取,而另一個則插入。如果你想這樣做,你需要鎖定,只是因爲你沒有看到任何問題並不意味着它永遠不會發生。