我有非常简单的代码,其中多个线程试图在std :: map中插入数据,根据我的理解,这会导致程序崩溃,因为这是数据竞争
std::map<long long,long long> k1map;
void Ktask()
{
for(int i=0;i<1000;i++)
{
long long random_variable = (std::rand())%1000;
std::cout << "Thread ID -> " << std::this_thread::get_id() << " with looping index " << i << std::endl;
k1map.insert(std::make_pair(random_variable, random_variable));
}
}
int main()
{
std::srand((int)std::time(0)); // use current time as seed for random generator
for (int i = 0; i < 1000; ++i)
{
std::thread t(Ktask);
std::cout << "Thread created " << t.get_id() << std::endl;
t.detach();
}
return 0;
}
然而,我运行了多次,没有应用程序崩溃,如果运行相同的代码与pthread和c ++ 03应用程序崩溃,所以我想知道是否有一些c ++ 11的变化使地图插入线程安全吗?
答案 0 :(得分:1)
不,std::map::insert
不是线程安全的。
您的示例可能无法崩溃的原因有很多。由于系统调度程序,您的线程可能以串行方式运行,或者因为它们很快完成(1000次迭代不是那么多)。您的地图将快速填满(仅有1000个节点),因此后来的插入实际上不会修改结构并减少崩溃的可能性。或者您使用IS线程安全的实现。
答案 1 :(得分:0)
对于大多数标准库类型,唯一的线程安全保证是在单独的线程中使用单独的对象实例是安全的。就是这样。
并且std::map
不是该规则的例外之一。实施可能会为您提供更多保证,或者您可能会变得幸运。
当涉及到修复线程错误时,只有一种运气。