2013-02-13 56 views
7

मुझे एक समस्या थी (segfault) सी ++ 11 में एक बहुप्रचारित कोड चला रहा था।सी ++ 11 std :: वेक्टर समवर्ती वातावरण में

#include <vector> 
#include <thread> 

std::vector<int> values; 
int i; 

void values_push_back() 
{ 
    values.push_back(i); 
} 

int main() 
{ 
    while(true) 
    { 
     std::vector<std::thread> threads; 

     for(i=0; i<10; ++i) 
     { 
      std::thread t(values_push_back); 
      threads.push_back(std::move(t)); 
     } 
     for(i=0; i<10; ++i) 
      threads[i].join(); 
    } 

    return 0; 
} 

और यहाँ gdb पर पश्व-अनुरेखन: http://pastebin.com/5b5TN70c

क्या है कि में गलत क्या है यहाँ यह कोड है?

+0

कृपया hmjds जवाब पर मेरी टिप्पणी देख सकते हैं और बीएल नहीं है इंडी अपने कोड की प्रतिलिपि बनाएँ। – inf

उत्तर

11

यह आगे बढ़ने से असंबंधित है।

एकाधिक सूत्र एक ही vector लेकिन vector::push_back() पर vector::push_back() को क्रियान्वित कर रहे हैं threadsafe नहीं है। vector में संशोधनों को सिंक्रनाइज़ करने की आवश्यकता है।

एक std::mutexpush_back() के लिए कॉल सिंक्रनाइज़ करने के लिए इस्तेमाल किया जा सकता:

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back() 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

इसके अलावा, चर i धागे के बीच तुल्यकालन है जो एक रेस स्थिति में परिणाम होगा बिना (इस के संभावित परिणाम है साझा की जा रही है डुप्लिकेट int एस vector में जोड़ा गया)। धागा करने के लिए एक तर्क के रूप int मूल्य गुजर से बचने के लिए पर विचार करें:

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back(int i) 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

for (int i = 0; i < 10; ++i) 
{ 
    threads.push_back(std::thread(values_push_back, i)); 
} 

for (auto& t: threads) t.join(); 

टिप्पणी की के रूप में bamboonstd::lock_guard पसंद से सुनिश्चित करने के लिए ताला जारी की है अगर push_back() फेंकता है (इस मामले में केवल bad_alloc() हो सकता है जो लेकिन यदि vector परिवर्तन और अधिक जटिल वस्तुओं कि कंस्ट्रक्टर्स फेंक है धारण करने के लिए इसे और अधिक महत्वपूर्ण हो जाता है):

void values_push_back(int i) 
{ 
    std::lock_guard<std::mutex> lk(values_mutex); 
    values.push_back(i); 
} 
+0

मेरे पास एक और जटिल समस्या थी जिसे मैं एक साधारण कोड के साथ पुन: उत्पन्न नहीं कर सकता। उसके लिए माफ़ करना। – deepskyblue86

+9

आपका कोड अपवाद-सुरक्षित नहीं है। यदि push_back फेंकता है, तो आप डेडलॉक करेंगे, इसके बजाय 'std :: lock_guard' का उपयोग करें। – inf

+1

@ बांसबन, अच्छा बिंदु और अपडेट किया गया। – hmjd