我有一个多线程程序,其中一个线程正在迭代一个列表,只读取值,而第二个线程正在从中删除一些元素:
std::list<Type> items;
void* Thread1(void*)
{
while(true)
for(auto item = items.begin(); item != items.end(); ++item) {
cout << item << std::endl;
sleep(1);
}
}
void* Thread2(void*)
{
for(auto item = items.begin(); item != items.end(); ++item) {
if(/*check some condition on item*/) {
items.erase(item);
break;
}
}
}
我不能在Thread1
的整个for循环上放置互斥锁,因为该列表非常大,这会导致整个程序变慢。
此外,Thread2
将被多次调用,我们无法确定何时会发生,而Thread1
必须一直监视列表。
有没有一种线程安全的方法来迭代一个大小可以实时更改的列表,而不会得到分段故障、未定义行为或可能跳过某些元素?
std::list::erase
中的“...被删除元素的引用和迭代器将失效...”这一点。如果删除线程和迭代线程位于同一元素上,则会使item
失效。 - Richard Crittenstd::list
不是线程安全的,需要进行某种形式的锁定。 - Sam Varshavchik