So we created a map. We want to get some_type blah = map_variable[some_not_inserted_yet_value]
this would call add new item to map if one was not previosly created. So I wonder if read is really thread safe with std::map
or it is onl开发者_运维知识库y possible to thread safly try{ ...find(..)->second...
?
The idea that calling find(...)->second
is thread-safe is very dependent of your view of thread-safety. If you simply mean that it won't crash, then as long as no one is mutating the dictionary at the same time you're reading it, I suppose you're okay.
That said, indeed, no matter what your minimum thread safety requirements are, calling the operator[]
method is inherently not thread-safe as it can mutate the collection.
If a method has no const
overload, it means it can mutate the object, so unless the documentation indicates methods are thread-safe, the method is very unlikely to be.
Then again, a const
method might not be thread-safe as well, because your object could depend on non-const
global state or have mutable
fields, so you'll want to be very, very careful if you use unsynchronized classes as if they were.
If you're 100% sure that the map contains the key, then it is technically thread-safe if all other threads are also only invoking read-only methods on the map. Note however, that there is no const
version of map<k,v>::operator[](const k&)
.
The correct way to access the map in a thread-safe fashion is indeed:
map<k,v>::const_iterator match = mymap.find(key);
if ( match != mymap.end() ) {
// found item.
}
As stated before, this only applies if all concurrent access is read-only. One way this can be guaranteed is to use a readers-writers lock.
Note that in C++03, there is no mention of threads in the standard, so even that is not guaranteed to be thread-safe. Make sure to check your implementation's documentation.
Standard library containers have no notion of thread safety. You have to synchronize concurrent read/write access to the container yourself.
try
has nothing to do with multithreading. It's used for exception handling.
find
does not throw an exception if the key is not found. If the key is not found, find returns the map's end()
iterator.
You are correct, operator[]
is not "thread safe" because it can mutate the container. You should use the find
method and compare the result to std::map::end
to see if it found the item. (Also notice that find
has a const
version while operator[]
does not).
Like others have said, the version of C++ before C++11 has no notion of threads or thread safety. However, you can feel safe using find
without synchronization because it doesn't change the container, so it's only doing read operations (unless you have a weird implementation, so make sure to check the docs). As with most containers, reading from it from different threads won't cause any harm, however writing to it might.
精彩评论