假设我有std :: vector和两个线程。
第一个线程正在处理擦除函数,而第二个线程处于 for循环
这种情况是线程安全的吗?
第二个线程会继续运行还是抛出异常?
#include <iostream>
#include <vector>
#include <thread>
int main()
{
std::vector<int> intContainer;
for ( int index = 0; index <= 100000; ++index){
intContainer.push_back(index);
}
std::thread t1([&](){
while ( 1 ){
intContainer.erase( std::find(intContainer.begin(), intContainer.end(), random(1, 100000) ) );
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
});
std::thread t2([&] (){
for ( auto& val : intContainer ){
std::cout << val << std::endl;
}
});
t1.join();
t2.join();
return 0;
}
答案 0 :(得分:6)
这是线程不安全的,但也是未定义的行为。
它是线程不安全的,因为在迭代时要更改元素(以及向量本身)。
由于上述几点(种族),它是未定义的行为,而且还因为您基本上擦除了向量中任何位置的元素,这意味着您实际上使所有对其的迭代器无效(您正在其他线程中进行迭代) )。因此,即使这是一个单线程程序(例如使用光纤),您仍然会拥有UB。
请注意,由于某些内容不是线程安全的,因此不会引发异常。当然,这并不意味着不会发生错误(例如损坏,崩溃等),并且可以肯定地发生。
此外,请注意,线程(它们都不是)都将“停止运行”。他们将继续前进,而不知道自己搞砸了一切。关键是他们没有办法知道。