Reputation: 9432
Assuming I have a vector containing shared_ptrs to items:
std::vector<std::shared_ptr<Foo>> items;
Is it safe to iterate through items in that vector in one thread:
thread1()
{
for( auto foo : items )
{
foo->something();
}
}
While another thread removes items from that vector?
thread2()
{
items.erase( std::remove_if( items.begin(), items.end(),
[](std::shared_ptr<Foo>& foo){
return foo->shouldBeRemoved();
}));
}
So in other words: If thread2 removes an item while thread1 is accessing it, will the vector itself remain valid / corruption-free?
I'm well aware, in this example, that its up to me to make sure Foo::something() and Foo::shouldBeRemoved() does not cause any problems should both threads hit the same ptr at the same time.
And I know if the vector directly contains instances of Foo() thread 2 could delete something while thread 1 once attempting to use it. The use of the shared_ptr in theory should prevent the referenced object from being deleted while in use, so its the iterators / integrity of the vector that are in question.
Update: For anybody else with similar questions struggling to fine good quick-reference documentation on this kind of thing, this seems to cover it for my purpose:
http://en.cppreference.com/w/cpp/container#Thread_safety
Iterator operations (e.g. incrementing an iterator) read, but do not modify the underlying container, and may be executed concurrently with operations on other iterators on the same container, with the const member functions, or reads from the elements. Container operations that invalidate any iterators modify the container and cannot be executed concurrently with any operations on existing iterators even if those iterators are not invalidated.
SO answer summing up iterator invalidation rules: Iterator invalidation rules
Upvotes: 0
Views: 681
Reputation: 31
No! The iterator in thread1 becomes invalid if another thread adds or removes a element from items.
This is similar to items.remove returning a new and valid iterator so you can continue iteration while removing elements from a collection.
Upvotes: 3