In c++11 are the hash function class objects declared in <functional>
thread safe? E.g., is it safe to call this function from multiple threads?
size_t hash1(const std::string& s) {
std::hash<std::string> str_hash;
return str_hash(s);
}
or, if one has a global object std::hash<std::string> str_hash_global;
, then is it safe to call this second function from multiple threads?
size_t hash2(const std::string& s) {
return str_hash_global(s);
}
Based on this, when I'm setting the function the std::function object points to, for this use case the std::function object is not thread safe.
It's safe to read and write to one instance of a type even if another thread is reading or writing to a different instance of the same type. For example, given objects A and B of the same type, it's safe when A is being written in thread 1 and B is being read in thread 2.
None of the STL containers is thread safe, so std::set in particular isn't. In your case, the issue isn't even really thread safety, though: You simply share an object across multiple threads (fine) and modify it in one thread (fine as well).
std::hash<const char*> produces a hash of the value of the pointer (the memory address), it does not examine the contents of any character array.
The standard library promises that if you only call const
-qualified member functions on a standard library object, the standard library code does not cause a data race (cf. [res.on.data.races]).
The standard template std::hash
, as well as all its permissible specializations, as well as any user-provided functor that meets the Hash
requirements ([hash.requirements]) must have a const
-qualified call operator due to the requirements, and thus using the library-provided std::hash
specializations should not cause a race. Moreover, due to [namespace.std], program-provided specializations must meet the same requirements.
Finally, I imagine that you would usually use the race-freeness guarantees by recursively appealing to const
calls: If you multiple threads concurrently look up values in a map, they have to use the map's const
interface to invoke the above library rule, but then the map only gets to use a constant value of the hasher (or a private copy), and so it can itself only perform race-free hash computations. Whether a racy non-const call operator exists is immeterial at that point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With