I have a program which uses a lot of std::map
structures. Now I want to use them with with multiple threads and assume that inserting or deleting keys will potentially alter the whole data structure and break it in parallel. But when I do not add new keys, it should be fine, right?
The following program shows what I want to do:
#include <omp.h>
#include <iostream>
#include <map>
int main(int const argc, char const *const *const argv) {
// Take a map and allocate the elements, but not fill them at this point.
std::map<int, int> map;
int size = 10000;
for (int i = 0; i < size; ++i) {
map[i];
}
// Go through the elements in parallel and write to them, but not create any
// new elements. Therefore there should not be any allocations and it should
// be thread-safe.
#pragma omp parallel
{
int const me = omp_get_thread_num();
#pragma omp for
for (int i = 0; i < size; ++i) {
map[i] = me;
}
}
// Now all threads access all the elements of the map, but as the map is not
// changed any more, nothing bad should happen.
#pragma omp parallel
{
int const me = omp_get_thread_num();
int self = 0;
for (int i = 0; i < size; ++i) {
if (map[i] == me) {
++self;
}
}
#pragma omp critical(cout)
std::cout << "Thread " << me << " found " << self << " entries.\n";
}
}
Then I compile it with the following:
$ g++ -fopenmp -O3 -Wall -Wpedantic -g -fsanitize=address -o concurrent-map concurrent-map.cpp
This seems to work just fine with four threads. If I comment out the first for loop and let the threads populate the map, it crashes with segmentation faults, as I expect.
Of course I cannot prove that std::map
is thread-safe in the way I think this way, but it at least does not prove the negative. Can I use the std::map
in this fashion in parallel?