假设我有一个包含项目的shared_ptrs的向量:
std::vector<std::shared_ptr<Foo>> items;
在一个线程中迭代该向量中的项是否安全:
thread1()
{
for( auto foo : items )
{
foo->something();
}
}
当另一个线程从该向量中删除项目时?
thread2()
{
items.erase( std::remove_if( items.begin(), items.end(),
[](std::shared_ptr<Foo>& foo){
return foo->shouldBeRemoved();
}));
}
换句话说:如果thread2在访问它时删除了一个项目,那么 vector 本身是否仍然有效/无损?
我很清楚,在这个例子中,如果两个线程同时击中同一个ptr,由我来确定Foo :: something()和Foo :: shouldBeRemoved()不会导致任何问题
我知道如果向量直接包含Foo()的实例,则线程2在尝试使用它时可以删除某些内容。在理论上使用shared_ptr应该可以防止被引用的对象在使用时被删除,因此它是有问题的向量的迭代器/完整性。
更新 对于其他有类似问题努力在这类事情上做好快速参考文档的人,这似乎涵盖了我的目的:
http://en.cppreference.com/w/cpp/container#Thread_safety
迭代器操作(例如,递增迭代器)读取,但不是 修改底层容器,并可以与之同时执行 使用const在同一容器上的其他迭代器上的操作 成员函数,或从元素中读取。 集装箱业务 无效的任何迭代器都会修改容器而不能 与现有迭代器上的任何操作同时执行 如果这些迭代器没有失效。
SO回答总结迭代器失效规则: Iterator invalidation rules
答案 0 :(得分:2)
没有!如果另一个线程在项目中添加或删除元素,则thread1中的迭代器将变为无效。
这类似于items.remove返回一个新的有效迭代器,因此您可以在从集合中删除元素时继续迭代。