容器可以在没有任何锁定机制的情况下被访问,前提是所有涉及的线程都是读取器线程。
这里已经讨论了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;
}
正如所见,没有使用锁,这是有道理的,因为对于非线程应用程序来说,锁的开销并不是真正需要/不希望的。