I am having std::map< StudentName, Marks >
where StudentName
is std::string
and Marks
is an integer.
Now, in my application, multiple threads are accessing this map to:
- Find
StudentName
. If exist, increase itsMarks
. - Decrease
Marks
ofStudentName
. - Add
StudentName
to the map. - Delete
StudentName
from the map.
Question: What is the most efficient approach to do above operations on std::map
in a multi-threaded environment?
Current Solution:
The code that does all these operations on the map is put inside critical section. But this degrades performance.
(For example, If a thread is adding marks for a particular student, why do other threads who want to add marks for different students need to wait?)
This is what I think can be done:
I gathered info on multithreading on maps from other similar questions/answers on SO and here is what I think I need to do. Provided std::map
are not thread safe, (i.e. no other thread should access map when it is being updated)
- I want to put only last two (add/delete StudentName) activities exclusive (No other activity should be done in parallel while adding/deleting elements to/from map)
- Do not allow multiple threads to access same element of map (So that multiple threads cannot try to increase/decrease marks of same student simultaneously)
But I am not sure how can I achieve this (what thread synchronization objects/technologies can be used) I am developing this application on Windows through VS2010
Any suggestions or alternative approaches here please?
Update: Thanks for everyone's input. Unfortunately no atomic ints available in VS2010. So, here is what I plan to do based on your inputs. I'll have three kind of locks: On map: map_read_lock, map_write_lock On elements: element_write_lock (For each element)
Now,
When finding element in map: Get map_read_lock (This will allow me concurrent finds)
When adding/deleting elements to map: Get map_write_lock (This will prevent concurrent updates of the container, which I believe, is not recommended)
When changing values: Get (map_read_lock & element_write_lock) (This will allow parallel changes to different values, but will prevent concurrent change to the same value. Also, will prevent changes to values when container is being updated and vice versa)