2016-07-22 398 views
0

我有多个线程试图插入的std ::地图数据非常简单的代码和按我的理解这应该导致,因为这是数据种族程序崩溃std :: map在C++ 11中插入线程安全吗?

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

如果你的代码不是*可证明*线程安全的,那么你不应该认为它是。你不应该认为任何与线程有关的事情都可以,因为程序没有崩溃。 –

+0

是的,我明白了,但问题是我们在生产环境中使用的类似代码崩溃,代码崩溃了,因为地图内部树正在重新平衡,所以只想知道地图插入线程安全性的C++ 11中是否有任何更改,因为那里我们用phreads来使用C++ 03 – Kapil

回答

1

不,std::map::insert不是线程安全的。

您的示例可能不会崩溃的原因很多。由于系统调度程序,您的线程可能以串行方式运行,或者因为它们以非常快的速度完成(1000次迭代并不那么多)。您的地图将快速填满(只有1000个节点),因此后面的插入不会实际修改结构并减少崩溃的可能性。或者你正在使用的实现是线程安全的。

0

对于大多数标准库类型,唯一的线程安全保证就是在单独的线程中使用单独的对象实例是安全的。而已。

std::map不是该规则的例外之一。实施可能会为您提供更多的保证,或者您可能会幸运。

当谈到固定螺纹错误时,只有一种运气。