有兩個線程,其中一個將插入到地圖中和從地圖另一個將find
。C++地圖併發插入和讀出由兩個線程
map<string,object>* mapA;
如果線程A將配置對象插入到映射w.r.t中的字符串鍵。
當線程B將嘗試找到具有相同字符串鍵。如果不存在,它會再次嘗試,直到找到字符串鍵。
它會導致在此過程中崩潰或數據損壞,如果在同一時間線程A插入當線程B讀取密鑰?這裏需要同步嗎?
當用一個示例應用程序測試我不力面對任何類型崩潰或腐敗
有兩個線程,其中一個將插入到地圖中和從地圖另一個將find
。C++地圖併發插入和讀出由兩個線程
map<string,object>* mapA;
如果線程A將配置對象插入到映射w.r.t中的字符串鍵。
當線程B將嘗試找到具有相同字符串鍵。如果不存在,它會再次嘗試,直到找到字符串鍵。
它會導致在此過程中崩潰或數據損壞,如果在同一時間線程A插入當線程B讀取密鑰?這裏需要同步嗎?
當用一個示例應用程序測試我不力面對任何類型崩潰或腐敗
的容器的可在沒有任何鎖定機構被訪問,只有在所涉及的所有線程都讀取器線程。
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;
}
如所看到的,沒有鎖定使用,並且它是有道理的,因爲是不是真的需要/期望用於非線程應用鎖定的開銷。
基本上,你不知道會發生什麼,STL將不作任何承諾,該數據將隨時爲您從第一個線程讀取,而另一個則插入。如果你想這樣做,你需要鎖定,只是因爲你沒有看到任何問題並不意味着它永遠不會發生。
需要同步才能找到密鑰元素是否存在於容器中? –
還不清楚..你說的是_簡而言之,在你的情況下,因爲插入和查找都涉及不同的線程,所以需要鎖定._和下一行你告訴相反的事情,不需要鎖定。所以在我的情況下,線程A將插入一個鍵,同時該鍵被循環中的另一個線程(線程B)搜索(**只搜索**)。鎖是否需要? –
而不是去互斥或臨界區..我可以使用atomic_bool並做手動同步? –