0

My need is just like below: One thread (named thread 1)just keeps inserting pairs into the common map. And the other thread (named thread 2)keeps getting the element at the begin position(no matter if it is still the begin while other thread insert an element at the begin position) and do some operation to the element and erase the iterator.

I know that STL is not threadsafe, but it is still a good container to use. So my method is every time thread 2 get the element, I make a copy of it and do my work, and protect insert/delete/begin/end by one mutex.

pseudocode like below under c++17

my_map {
insert(){
 lock_guard(mutex)
 map.insert()
}
erase(){
 lock_guard(mutex)
 map.erase()
}
end(){
 lock_guard(mutex)
 map.end()
}
begin(){
 lock_guard(mutex)
 map.begin()
}}

thread 1:
while(1){
 sleep(1)
 my_map.insert()
}

thread 2:
while(1){
 auto it = my_map.begin()
 auto k = it->first;
 auto v = it->second;
 work(k, v);
 my_map.erase(it);
}

My question is would my code be threadsafe? And will insert in thread 1 affects the actual value of k and v in thread 2?(again no matter if it is at the real begin position, I just want to get k and v of the iterator when thread 2 gets using "auto it = my_map.begin()")

f1msch
  • 509
  • 2
  • 12
  • As an aside, I'd be tempted to use [`extract`](https://en.cppreference.com/w/cpp/container/map/extract) instead of holding onto the iterator during `work` – Caleth Nov 10 '21 at 12:13
  • Seems like a duplicate of "[How can map operations in one thread be done safely, without invalidate iterators in another?](https://stackoverflow.com/q/69915372/90527)", with the exception that the other question has a thread diagram. As such, voting to close this one in favor of the other (though updating this question and closing the other would be just as good). – outis Dec 28 '21 at 05:17

1 Answers1

3

It's not thread safe if the underlying map is std::unordered_map. With unordered_map insert may invalidate iterators (if rehasing occurs).

With std::map iterators aren't invalidated on insert so I think the code would be ok.

bolov
  • 72,283
  • 15
  • 145
  • 224