2013-02-13 6 views
7

hatte ich ein Problem (segfault) 11 einen multithreaded Code in C++ ausgeführt wird. Hier ist es der Code:C++ 11 std :: vector in Umgebung mit gemeinsamer Zugriff

#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; 
} 

Und hier das Backtrace auf GDB: http://pastebin.com/5b5TN70c

Was ist falsch daran?

+0

sie bitte meinen Kommentar auf hmjds Antwort sehen und nicht bl Ziehe seinen Code ab. – inf

Antwort

11

Dies ist in keinem Zusammenhang mit bewegt.

Mehrere Threads vector::push_back() auf demselben vector aber vector::push_back() ausführen nicht THREAD. Die Änderungen an der vector müssen synchronisiert werden.

A std::mutex könnte verwendet werden, um die Anrufe zu push_back() zu synchronisieren:

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

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

Auch die Variable i zwischen Threads ohne Synchronisation gemeinsam genutzt wird, die in einer Race-Bedingung (ein mögliches Ergebnis wird dies zur Folge haben ist Duplikat int s hinzugefügt, um die vector). Betrachten wir das Bestehen der int Wert als Argument für den Thread, dies zu vermeiden:

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

Wie kommentiert von bamboonstd::lock_guard bevorzugen die Sperre, um sicherzustellen, wird freigegeben, wenn push_back() wirft (die in diesem Fall nur bad_alloc() sein könnte, aber wenn die vector Änderungen komplexere Objekte zu halten, die Konstrukteure haben werfen wird es immer wichtiger):

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

Ich hatte ein komplexeres Problem, das ich mit einem einfachen Code nicht reproduzieren kann. Das tut mir leid. – deepskyblue86

+9

Ihr Code ist nicht ausnahmesicher. Wenn push_back löst, werden Sie deadlock, verwenden Sie stattdessen 'std :: lock_guard'. – inf

+1

@bamboon, guter Punkt und aktualisiert. – hmjd

Verwandte Themen