2013-02-13 19 views
7

C++ 11でマルチスレッドコードを実行する問題(segfault)がありました。ここC++ 11 std :: vector in concurrent environment

#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しないでくださいコードをインディにコピーしてください。 – inf

答えて

11

これは移動には関係ありません。

複数のスレッドが同じvectorvector::push_back()しかし vector::push_back()を実行しているスレッドセーフではありません。 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本の可能な結果がある(競合状態になりこれは同期せずにスレッド間で共有されています重複intvectorに追加されました)。この場合にのみbad_alloc()することができた(push_back()をスローした場合に解放され、ロックを確実にするためにstd::lock_guardを好むbamboonでコメントしたよう

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(); 

が、これを回避するために、スレッドの引数としてint値を渡して考えてみましょう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