Thread safety in C++
I have question regarding thread safety as below ( I have only two threads in which one of the threads only read from the map, the other threads would be writing and reading as shown):
//Thread 2: the reading and writing thread
unordered_map<int, unordered_map<classA*>*>testMap;
//need lock because writing to the map?
testMap[1] = new unordered_map<int, classA*>;
//do not need lock because only reading and the other thread is only reading?
unordered_map<classA*>* ptr = testMap[1];
//need lock because writing?
(*ptr)[1] = new classA;
//do not need lock because only reading and the other thread is only reading?
classA* ptr2 = (*ptr)[1];
//din't modify the map, but modify the data pointed by the pointer stored by the map, do I need lock?
ptr2->field1 = 5;
ptr2->field2 = 6;
//end开发者_StackOverflow中文版 of reading and writing thread
What is the correct way to lock to unordered_map? Also, should I use a single lock or multiple locks?
Thanks.
If your map is the only shared resource, a single mutex is sufficient.
You need to lock the writing in the first thread, and lock the reading in the second one. If you lock the map only when writing on it, the second thread could read it while you are writing in it.
You dont need a lock in the last example regarding the pointers, since you dont deal with any data stored in the map. Edit : in fact, it depends on what your are doing with the pointers and in which thread you do it.
You should read this great article : http://herbsutter.com/2010/09/24/effective-concurrency-know-when-to-use-an-active-object-instead-of-a-mutex/
You need to lock both, reading and writing. If you do not lock reading then a write can occur while you are reading and you may access the map in an inconsistent state.
What would be best in your situation would be a reader-writer-lock. Such a lock allows multiple readers to read at the same time but only one writer at the same time and no readers while a writer writes and vice versa.
Couple of things:
- You should consider smart pointers to store in your map.
- What you are doing is potentially quite dangerous (i.e. you may not be modifying the main map), but you are modifying what's stored there and if you do this outside of a lock, the end result could be anything - let's say that thread one has also read the same pointer and starts iterating whilst thread two is writing the instance of classA - what happens then?
I would have a lock around the main map, and then another lock for each payload map. Any operations on either map should require to obtain the lock at the correct level. I'd also be careful not to return iterators outside of the class that manages the lock, so basically you should implement all the methods you'd need within the class.
精彩评论