2016-07-22 90 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不是該規則的例外之一。實施可能會爲您提供更多的保證,或者您可能會幸運。

當談到固定螺紋錯誤時,只有一種運氣。