Can I access a C ++ 11 std :: map record when inserting / deleting from another thread?

Can I access (without blocking) the std :: map record and another thread inserts / erases the records?

Pseudo C ++ example:

typedef struct {
   int value;
   int stuff;
}some_type_t;

std::map<char,some_type_t*> my_map;   

//thread 1 does:
my_map.at('a')->value = 1;

//thread 2 does:
some_type_t* stuff = my_map.at('b');

//thread 3 does:
my_map.erase('c');

//I'm not modifying any elements T is a pointer to an previously allocated "some_type_t" 

std C ++ 11 says that all members should be thread safe (erase () is not const).

+4
source share
4 answers

No no no no!

map::erasechanges the relationships between map entries and interferes with the search algorithm used in map::at. You can use items while erasing, but you cannot execute the search algorithm itself!

. , - , . .

#include <iostream>
#include <thread>
#include <map>
#include <cassert>

std::map<int, int> m;

// this thread uses map::at to access elements
void foo()
{
  for (int i = 0; i < 1000000; ++i) {
    int lindex = 10000 + i % 1000;
    int l = m.at(lindex);
    assert(l == lindex);
    int hindex = 90000 + i % 1000;
    int h = m.at(hindex);
    assert(h == hindex);
  }
  std::cout << "OK" << std::endl;
}

// this thread uses map::erase to delete elements
void bar()
{
  for (int i = 20000; i < 80000; ++i) {
    m.erase(i);
  }
}

int main()
{
  for (int i = 0; i < 100000; ++i) {
    m[i] = i;
  }

  std::thread read1(foo);
  std::thread read2(foo);
  std::thread erase(bar);

  read1.join();
  read2.join();
  erase.join();

  return 0;
}
+9

. .

const , const (, const, , const, begin ..).

map set, , / / ( , , erase =).

erase insert , - const (, find at). , [] erase, .

const, const , , iterator &.

+11

No. std :: map are not thread safe. The Intel Thread Library (tbb) library has several parallel containers. Check tbb

0
source

As long as the threads do not access the same address at the same time, there will be no problems.

But there is no direct answer to your question, it is not thread safe, so you cannot do this without blocking without any errors.

-1
source