1

I have a global var std::unordered_map < std::string,int > themap .

the thread1 do the following :

Time1 : 
string s = "user1" ; 
themap[s] = 100 ;

Time2 :
string s = "user2" ;
themap[s] = 101 ;

the thread2 do the following :

Time2:
string s = "user1" ;
auto got = themap.find( s ) ;

Time1 happened before Time2 , suppose that in thread2 , got != themap.end() will be correct and got->second = 100 !!! What bother me is that , if in the very moment Time2 , thread1 is doing themap["user2"] = 101 , which will modify themap's memory structure , thread2 themap.find doing find at the exact same time thread1 modify themap's memory contents , if without lock , still I get got != themap.end() ? and got->second = 100 ?

themap["user2"] = 101 and got = themap.find( s )
doing at the exact same time will cause got->second not to 100 ?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
barfatchen
  • 1,630
  • 2
  • 24
  • 48
  • 1
    If there's no synchronization between these two threads, then you have a race condition and your program exhibits undefined behavior. Which means it can legally produce any outcome whatsoever. – Igor Tandetnik Oct 27 '15 at 23:59

2 Answers2

0

You can prevent the unorderd_map to change its internal structure, by forcing it to do so beforehand. Use reserve, and set max_load_factor to, or close to 1.0f.

  • Thanks , but themap contents will increase to an number can not be decided beforehand , thanks for kindly advice !! – barfatchen Oct 28 '15 at 00:27
  • @barfatchen You are welcame. You can check the load_factor every time you insert. If it is approaching max_load_factor, reserve eg. 50% more, and tell the other threads. Other solutions: Use just std::map instead, it is not considerably slower (just a bit). Alternatively you can define your own hash function that meets your criteria. – Csaba Bálint Oct 28 '15 at 00:35
0

It is true that unordered_map thread safe holds for one thread writing, and multiple threads reading.

Also in your example in Time 1 you are modifying "user1" , which is then searched in thread 2 at Time 2. The fact that you set "user2" in thread 1 at Time 2 is orthogonal.

About the internal memory being modified, that is not a problem because the iterators used by find initiated while you insert a new value will not be invalidated.

Therefore in your test case there is no race condition.

Community
  • 1
  • 1
g24l
  • 3,055
  • 15
  • 28