2016-09-01 2 views
0

Warum dies undefiniertes Verhalten verursachen?Emplace zurück Thread auf Vektor

#include <iostream> 
#include <thread> 
#include <vector> 

std::vector<std::thread> threads(3); 

void task() { std::cout<<"Alive\n";} 
void spawn() { 
     for(int i=0; i<threads.size(); ++i) 
       //threads[i] = std::thread(task); 
       threads.emplace_back(std::thread(task)); 

     for(int i=0; i<threads.size(); ++i) 
       threads[i].join(); 
} 

int main() { 
     spawn(); 
} 

Wenn ich Themen wie in Kommentarzeile Thread erstellt wird kopiert/verschoben Zuordnung so seine Ordnung, aber warum nicht funktioniert, wenn anstelle Thread zu schaffen?

+0

Bitte spezifischere über „nicht funktioniert“ und „nicht definiertes Verhalten“. Um ein Objekt in-place zu erstellen (d. H. Vollständig ellidierende Kopie), sollten Sie threads.emplace_back (task) ausführen. – Dmitry

+1

Die Threads, die Sie versuchen, beizutreten, sind nicht verbindbar. Der allgemeine Ratschlag für C++ lautet wie immer: Bevor Sie etwas Komplizierteres machen, vergewissern Sie sich, dass Sie * 'int' und' std :: vector 'vollständig verstehen. Gehen Sie nicht weiter, bis Ihnen beide völlig klar sind, und wenn Sie ein Problem haben, reduzieren Sie es zuerst auf "int" oder "std :: vector ". –

Antwort

4

Was passiert in Ihrem Code, dass Sie eine drei Standard-Threads erstellen und dann weitere 3 Threads hinzufügen.

Wechsel:

std::vector<std::thread> threads(3); 

An:

std::vector<std::thread> threads; 
const size_t number_of_threads=3; 

int main(){ 
    threads.reserve(number_of_threads); 
    spawn(); 
} 

Und innen spwan:

void spawn() { 
    for(int i=0; i<number_of_threads; ++i){ 
     threads.emplace_back(std::thread(task)); 
    } 
    for(int i=0; i<threads.size(); ++i){ 
     threads[i].join(); 
    } 
} 

Wenn Sie emplace_back oder psuh_back verwenden, müssen Sie nicht auf den Speicher zuweisen, bevor. Sie sollten nur reserve es.

BTW, da Sie emplace_back nicht verwenden push_back Sie können auch direkt schreiben:

threads.emplace_back(task); 
+0

Beachten Sie, dass threads.size() auch dann zurückgegeben wird, wenn Sie Kapazität reserviert haben, und threads.capacity() eine beliebige Zahl> = 3 zurückgibt. Daher muss die erste Schleife in spawn() denselben Wert verwenden (vorzugsweise dieselbe Variable oder Konstante), die an reserve() übergeben wurde. Und in diesem speziellen Fall gibt es wahrscheinlich nichts zu gewinnen, wenn man reserve() aufrufen würde. – Jeremy

+0

Sie haben Recht mit dem ersten Teil, den ich verpasst habe. Aber es gibt in der Tat einen Gewinn durch die Verwendung von Reserve, die eine Neuzuteilung verweigert, die passieren könnte. –

+1

Nur wenn die Implementierung den Vektor in Inkrementen kleiner als die von Ihnen reservierte Größe vergrößert - was in diesem speziellen Fall höchst unwahrscheinlich ist. – Jeremy

Verwandte Themen