Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL vector iterator vs indexes access and thread safety

I am iterating over an STL vector and reading values from it. There is another thread which can make changes to this vector. Now, if the other thread inserts or removes and element from the vector, it invalidates the iterator. There is no use of locks involved. Does my choice of accessing the container through indexes(Approach 1) in place of iterators(Approach 2) make it thread safe? What about performance?

struct A{int i; int j;};

Approach 1:

   size_t s = v.size();//v contains pointers to objects of type A
    for(size_t i = 0; i < s; ++i)
    {
         A* ptr = v[i];
         ptr->i++;
    }

Approach 2:

std::vector<A*>::iterator begin =  v.begin();
std::vector<A*>::iterator end =  v.end();
for(std::vector<A*>::iterator it = begin; it != end; ++it)
{
     A* ptr = *it;
     ptr->i++: 
}
like image 712
sank Avatar asked Dec 27 '22 01:12

sank


1 Answers

The thread-safety guarantees for standard library containers are very straight forward (these rules were added in C++ 2011 but essentially all current library implementations conform to these requirements and impose the corresponding restrictions):

  1. it is OK to have multiple concurrent readers
  2. if there is one thread modifying a container there shall be no other thread accessing (reading or writing) it
  3. the requirements are per container object

Effectively, this means that you need to use some mechanism external to the container to guarantee that a container accessed from multiple threads is handled correctly. For example, you can use a mutex or a readerwriter lock. Of course, most of the time containers are accessed only from one thread and things work just fine without any locking.

Without using explict locks you will cause data races and the behavior is undefined, independent of whether you use indices or iterators.

like image 73
Dietmar Kühl Avatar answered Jan 27 '23 13:01

Dietmar Kühl