C ++ 11 std :: hash functions object classes thread safety

In C ++ 11 - hash function class objects declared thread safe in <functional> ? For example, 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 you have 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); } 
+5
source share
2 answers

The standard library promises, which, if you only call const -qualified member functions on the standard library object, the standard library code does not cause data race (see [res.on.data.races]).

The standard std::hash template, as well as all of its valid specializations, as well as any user-provided functor that meets the requirements of Hash ([hash.requirements]), must have a const -qualified call statement due to requirements, and thus using the std::hash specializations provided by the library should not cause a race. In addition, because of [namespace.std], specialized specializations must meet the same requirements.

Finally, I assume that you usually use guarantees of racial freedom by recursively calling const calls: if multiple threads are simultaneously viewing values ​​on a map, they should use the map const interface to invoke the library rule above, but then the map only gets a constant hash value ( or private copy), and therefore she herself can only perform hashing without racing. Regardless of whether there is any explicit contactless call operator, it is invisible at this point.

+6
source

The same "thread safety" rules apply as for all types of std :: lib.

The first version guarantees thread safety, since there are no variables between the threads.

The second one guarantees the absence of data calculations if the called operator() const . It is not known whether the implementation provides an additional (insecure) non-constant overload of hash<T>::operator() in addition to the (required) constant. If your global_str_hash is const or you pass it to const before using it, you guarantee that const operator() will be used.

There is no reason to make the second version, this is just silly, but in practice it should be safe, because no standard library implementation will most likely provide reliable non-constant hash::operator() overloading, they will only provide const overloading, which should be thread safe.

+2
source

Source: https://habr.com/ru/post/1238783/


All Articles