开发者

is `std::map<..> a; blah = a[abcd];` thread safe if abcd was not created before this call?

开发者 https://www.devze.com 2023-03-30 17:17 出处:网络
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 threa

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消