问题
Is it safe to use std map without a lock in multi-thread environment? Where It is guaranteed that two threads never be manipulating the same entry in the map.
There is already a question on this but I am particularly interested in the case where multiple threads are accessing different entries in the map. particularly unordered maps.
回答1:
It is safe as long as none of the threads are modifying the map. It is also safe if threads are modifying different elements of the map (provided the elements themselves don't cause race conditions by, for example, modifying some global state):
In 17.6.5.9 Data race avoidance, the standard library guarantees that concurrent const
access to containers is safe (at least as far s the containers go. If the elements allow mutation via const
access there could be data races at the element level.)
In 23.2.2 Container data races further guarantees are made: non-const concurrent access is safe if the modifications/reads are to different elements of the container1.
As soon as you have one thread making modifications to the container or to the same element in the container while others read or write, you are open to race conditions and undefined behaviour.
1 With the exception of std::vector<bool>
回答2:
Threads accessing only const members of a map will not race with each other. This is specified in the requirements on library types, at the beginning of the library specification.
Threads accessing non-const members can race with threads accessing const or non-const members.
In other words, they're like pretty much any other object and have no extra thread safety guarantees. The standard library does not currently contain special thread safe containers.
回答3:
As per C++11 23.2.2 Container data races /2
:
Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting
vector<bool>
, are modified concurrently.
Section 17.6.5.9
simply states the limitations applied to the implementation so that it won't cause data races.
That text basically means you have to handle your own race conditions, the containers themselves don't do this.
回答4:
Is it safe to use std map without a lock in multi-thread environment? Where It is guaranteed that two threads never be manipulating the same entry in the map.
You can freely manipulate different existing entries in the map (only the values, as the map APIs forbid mutation of the keys) but should use some synchronisation facility to write out the changes before any other thread attempts to access or mutate them.
For unordered_map
, insert
(even by []
), emplace
, erase
, reserve
, rehash
(explicit or automatic), operator=
, clear
can't be done safely while other threads are doing more than accessing/mutating elements that they had already found the addresses of, as the above functions can modify the underlying hash table data structure and per-bucket linked lists that track elements. "more than" includes things like find
, []
even on an existing element, at
, equal_range
, even empty
, size
and load_factor
and all the bucket
operations.
来源:https://stackoverflow.com/questions/29226578/thread-safety-in-stdmap