[英]stl map find thread safe
在stl map線程上找到調用是否安全?
不,C ++規范不保證任何STL容器上的操作規范中的線程安全性。 如果線程安全很重要,您應該提供自己的鎖定。
話雖這么說,不同的實現似乎提供了不同的保證。 例如,大多數似乎允許多個並發讀取器,只要不同時執行寫入。 如果您不關心可移植性,可以研究實現的文檔。 例如,從這里為SGI STL:
STL的SGI實現僅在對不同容器的同時訪問是安全的意義上是線程安全的,並且對共享容器的同時讀取訪問是安全的。 如果多個線程訪問單個容器,並且至少有一個線程可能寫入,則用戶負責確保在容器訪問期間線程之間的互斥。
從這個答案來看,Dinkumware似乎也提出了類似的保證(他們制作了微軟的STL實現)。
多個線程可以安全地讀取相同的容器對象。 (容器對象中有nunprotected mutable子對象。)
兩個線程可以安全地操作相同類型的不同容器對象。 (容器類型中沒有不受保護的共享靜態對象。)
如果至少有一個線程正在修改對象,則必須防止同時訪問容器對象。 (明顯的同步原語,例如Dinkum線程庫中的原語,不會被容器對象破壞。)
我試圖找到問題的答案。
https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-3.4/stl__map_8h-source.html
你可以看到stl map souce。
搜索find()
。 它發現於497行,524行。 代碼寫為_M_t.find(__x);
然后搜索_M_t
。
它在124行中找到。 它寫成_Rep_type _M_t;
如果為每個線程創建屬性_M_t
,則它可以是線程安全的。 但我不這么認為。 如果2線程使用find
同時,他們會使用_M_t
兼任。 _Rep_type
連接到_Rb_tree
。
你可以在下面的源代碼中看到_Rb_tree
。
https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.1/stl__tree_8h-source.html
find()
做樹旅行(見下面的代碼)。 不會發生__x
和__y
變化。
01307 template<typename _Key, typename _Val, typename _KeyOfValue,
01308 typename _Compare, typename _Alloc>
01309 typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
01310 _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
01311 find(const _Key& __k)
01312 {
01313 _Link_type __x = _M_begin(); // Current node.
01314 _Link_type __y = _M_end(); // Last node which is not less than __k.
01315
01316 while (__x != 0)
01317 if (!_M_impl._M_key_compare(_S_key(__x), __k))
01318 __y = __x, __x = _S_left(__x);
01319 else
01320 __x = _S_right(__x);
01321
01322 iterator __j = iterator(__y);
01323 return (__j == end()
01324 || _M_impl._M_key_compare(__k,
01325 _S_key(__j._M_node))) ? end() : __j;
01326 }
否:當另一個線程與您的find
同時更新地圖時,行為未定義。
實際上,Microsoft Visual Studio 2008附帶的STL似乎對修改映射的操作有一些鎖定(我假設它與set相同)。 這是相當煩人的,因為我正在多個線程中構建更多的地圖,這正在扼殺我的表現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.