C ++ std :: Vektor von unabhängigen std :: threads

7

Ich baue eine Echtzeit-Software, wo ich eine Haupt-Endlosschleife auf main() und Threads zum Lesen und Verarbeiten von Daten habe.

Eines der Probleme besteht darin, ein std::vector der laufenden Threads beizubehalten, um Signale an sie zu senden und die Ausführung zu überwachen. Also habe ich diesen Code zusammengestellt:

%Vor%

Es kompiliert nicht, diesen Fehler erhalten:

%Vor%

Die Threads sind unabhängig voneinander, also muss ich join weder für das Hauptprogramm noch für einen Thread aufrufen ...

Also, hier sind meine Zweifel:

Warum kompiliert mein Code nicht?

Ist das der richtige Weg den Vektor von Threads zu speichern?

Danke für Ihre Hilfe ...

PS: Originalcode hier :

    
Mendes 10.06.2015, 22:12
quelle

3 Antworten

11

Sie müssen etwas wie

verwenden %Vor%

Dies macht th zu einem rvalue und bewirkt, dass der move ctor aufgerufen wird. Der copy ctor von thread wurde designed deaktiviert (siehe Anthony Williams ' deaktiviert http://www.manning.com/williams/"> C + + Concurrency In Action ).

    
Ami Tavory 10.06.2015, 22:18
quelle
6
%Vor%

Lässt das etwas zurück schälen.

%Vor%

Ihr Code macht etwas, das versucht, ein std::thread einzuführen.

%Vor%

push_back ist der Täter.

std::thread ist nicht kopierbar - was würde bedeuten, einen Thread zu kopieren?

%Vor%

So Instanzen von std::thread -Objekten sollen eindeutige Besitzer sein. Abgesehen von der einfachen Verwirrung würde viel Schmerz folgen.

Sie sind jedoch beweglich.

%Vor%

t1 ist kein gültiger Thread-Deskriptor mehr, der Thread, den er beschreibt, gehört jetzt t2 .

Um solche Dinge in einen Container zu legen, können Sie entweder std::move oder std::emplace / std::emplace_back verwenden.

%Vor%

Während sich Ihr Code auf dieses spezielle Problem konzentriert, möchte ich darauf hinweisen, dass der C ++ - Standard dies als Fehler für einen Thread-Destruktor deklariert, der aufgerufen wird, während ein Thread noch angehängt und nicht verbunden ist.

%Vor%

Wenn main beendet wird, wird t1. ~ thread () aufgerufen, wodurch erkannt wird, dass der Thread noch angehängt und nicht verbunden ist. Dies führt zu einer Ausnahme, die einen Systemabsturz verursacht.

Entweder muss join() der Thread sein, warten bis er beendet wird oder detach() it. Sie müssen einen Weg finden, den Thread anzuhalten, wenn Sie join() verwenden wollen, und wenn Sie detach() verwenden, kann das Programm mitten im Thread enden und etwas wie das Schreiben von Daten usw. tun, was zu einem schwerwiegenden Fehler führt.

%Vor%

Hier verwenden wir ein Versprechen, den Thread wissen zu lassen, wann es Zeit ist zu laufen, aber Sie könnten Bedingungsvariablen, Signale usw. verwenden oder auch nur ein einfaches std::atomic<bool> ok_to_run { true }; , das Sie auf false testen.

    
kfsone 10.06.2015 22:57
quelle
2

Eine andere Variante, die funktioniert, besteht darin, Ihr Thread-Objekt im Aufruf von vector.push_back zu erstellen. Keine Notwendigkeit, std :: move in diesem Fall aufzurufen, da es bereits ein rvalue (also wird es verschoben werden).

%Vor%     
Seth 03.01.2016 04:38
quelle