2013-02-13 301 views
7

我有一個問題(段錯誤)在C++ 11中運行多線程代碼。這是代碼:併發環境中的C++ 11 std :: vector

#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回答我的評論和不BL indly複製他的代碼。 – inf 2013-02-14 22:06:56

回答

11

這與移動無關。

多個線程在同一vectorvector::push_back()執行vector::push_back()不是線程安全的。需要對vector的修改進行同步。

std::mutex可以用來調用同步push_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 s被添加到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(); 

正如評論說bamboon喜歡std::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 2013-02-13 18:22:58

+9

您的代碼不是異常安全的。如果push_back拋出,則會死鎖,請改用'std :: lock_guard'。 – inf 2013-02-14 22:04:50

+1

@bamboon,好點,並更新。 – hmjd 2013-02-15 08:43:37

相關問題