Are functions called by a concurrent unordered map look-up thread safe?

Viewed 70

Suppose I have the following code:

#include<concurrent_unordered_map.h>

struct firstStruct {
<irrelevant code>
}
struct secondStruct {
    void func(){ 
       <CRITICAL CODE>
    }
}

Let's suppose I have this:

concurrent_unordered_map<firstStruct,secondStruct> cmap = ...

and let's assume that that cmap has been populated, and that firstStruct f and secondStruct s are a (key,value) pair (f,s) that exist in cmap.

If I were to use the following code snippet

cmap[f].func();

Would the execution of the <CRITICAL CODE> in func() from secondStruct s be thread-safe?

Additionally, what would happen if I had the following code snippets, potentially being executed at the same time in different threads?

cmap[f].func();

and

SecondStruct s2 = ... ;
cmap[f] = s2;

If the (key,value) pair (f,s) was changed to (f,s2) by one thread, what would happen if another thread happens to be executing the <CRITICAL CODE>?

1 Answers

From the proposal for concurrent_unordered_map

For serialized execution, the operations behave the same as their current STL counterparts. The only change is allowance for concurrency. Executing any of the following operations concurrently on a concurrent unordered container does not introduce a data race:

get_allocator
empty, size, max_size
begin, end, cbegin, cend
insert
find, count, equal_range, operator[], at
load_factor
max_load_factor() 
operator==, operator!= 

assuming that the requisite operations on the key type (and mapped_type if applicable) are concurrency safe.

emphasis mine

So, operartor[] is thread safe but the operation that you do with it's return value must also be thread safe to guarantee no data race happens. That means the <CRITICAL CODE> in func() must be thread safe itself. If it is not then something like

cmap[f].func();
SecondStruct s2 = ... ;
cmap[f] = s2;

Would also not be thread safe as the function would still be running while you assign a new object to the key.

Related