Note: fundamentally edited answer
As a reflex, I would put a lock.
At first glance, it seems you don't need to set a lock in your case:
- For
insert() he said that "concurrent access to existing elements is safe, although there is no iteration of ranges in the container." - For
at() he said that: "Accessing or modifying other elements at the same time is safe."
The standard library addresses thread-safe aspects:
23.2.2. Container Racing
1) In order to avoid data investigations (17.6.5.9), implementations should consider the following functions as const: start, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at and, in addition to associative or disordered associative containers, operator [].
2) Despite (17.6.5.9), to avoid data jumps when the contents of the contained object in different elements in the same sequence , except for the vector, change simultaneously.
There are several other SO answers that interpret this as a thread safe guarantee, as I originally did.
However, we know that iterative ranges in the container are unsafe when the insert is done. And access to the element requires before you somehow repeat the search for the element. Thus, although the standard clarifies security for compatible access to various elements, when you already have your address, the wording leaves the potential concurrency container open.
I tried a simulation script with multiple reads and single write on MSVC and it never worked. But itβs not so important to do so: implementations are allowed to avoid more data than what is known in the standard (see 17.5.6.9) (or maybe I just got lucky many times).
Finally, I found two serious (post C ++ 11) links that clearly state that user locking should be safe:
GNU document on concurrency in the standard library : βThe standard establishes requirements for the library to ensure that race data are not caused by the library itself (...) User code must protect against simultaneous calls to functions that access any particular state of the library object when one or more of them refer to a state change. "
GotW # 95 Solution: Thread Security and Synchronization, Herb Sutter : "Is the code (...) correctly synchronized? No. There is one reading of the stream (through const operations) from some_obj in the code and a second stream writing the same variable. If these threads can run at the same time, this is a race and a direct non-stop ticket to the undefined behavior of the earth. "
Based on these two almost authoritative interpretations, I revise my first answer and return to my original reflection: you will have to block simultaneous access.
Alternatively, you can use non-standard libraries with parallel implementation of maps, for example, Microsoft concurrent_unordered_map from the parallel template library or Intel concurrent_unordered_map from Threading Building Blocks (TBB) or without blocking, as described in this SO answer