Bekomme den Rückgabecode von std :: thread? [Duplikat]

8

Gibt es trotzdem einen Rückgabecode von einem std :: thread? Ich habe eine Funktion, die eine ganze Zahl zurückgibt, und ich möchte in der Lage sein, den Rückgabecode von der Funktion zu erhalten, wenn der Thread fertig ausgeführt wird.

    
whoosy 07.09.2012, 14:23
quelle

4 Antworten

17

Nein, dafür steht std::thread nicht.

Verwenden Sie stattdessen async , um eine future :

zu erhalten %Vor%

Sie können die wait_for Member-Funktion von f (mit Null-Timeout) verwenden ) um zu sehen, ob das Ergebnis bereit ist.

    
Kerrek SB 07.09.2012 14:28
quelle
14

Kerrek SB ist mit seiner Antwort richtig, aber ich schlug vor, ein weiteres Beispiel hinzuzufügen (was er vorgeschlagen hat, sollte eine Antwort sein, also hier ist es).

Ich habe kürzlich entdeckt, dass zumindest in VC11 std::async gibt nicht alle Ressourcen des Threads bis zum Ende der Anwendung frei , wodurch Speicherverlust falsch positiv erreicht werden kann (falls dies der Fall ist) B. mit Visual Leak Detector überwachen.

Hier meine ich, dass es sich in den meisten grundlegenden Anwendungen nicht lohnt, den Rest dieser Antwort zu betrachten, aber wenn Sie wie ich Speicherlecks überprüfen müssen und es sich nicht erlauben können, falsch positives zu lassen wie statische Daten, die am Ende der Hauptfunktion nicht freigegeben werden. Wenn es Ihr Fall ist, dann könnte dies helfen.

std::async kann nicht standardmäßig in einem separaten Thread ausgeführt werden , wenn Sie std::launch::async als ersten Parameter verwenden. Andernfalls entscheidet die Implementierung, was zu tun ist, und deshalb wird die VC11-Implementierung den neuen Microsoft Concurrency Runtime-Task-Manager verwenden, um die bereitgestellte Funktion als Task in einem Task-Pool zu verwalten, wodurch Threads verwaltet und transparent verwaltet werden. Es gibt Möglichkeiten, den Taskmanager explizit zu beenden, aber das ist zu plattformspezifisch, was async zu einer schlechten Wahl macht, wenn Sie genau 1) sicher sein wollen, einen Thread zu starten und 2) später ein Ergebnis erhalten und 3) sicher sein müssen vollständig freigegeben, wenn Sie das Ergebnis erhalten .


Die Alternative, die genau das tut, ist die Verwendung von std::packaged_task und std::thread in Kombination mit std::future . Die Art und Weise, wie es gemacht wird, ist der Verwendung von std::async ähnlich, nur etwas ausführlicher (was bedeutet, dass Sie es in einer benutzerdefinierten Template-Funktion verallgemeinern können, wenn Sie möchten).

%Vor%

Zuerst erstellen wir eine Aufgabe, im Grunde ein Objekt, das sowohl die Funktion als auch std::promise enthält, die der Zukunft zugeordnet werden. std::packaged_task funktioniert meistens wie eine erweiterte Version von std::function :

Jetzt müssen wir den Thread explizit ausführen:

%Vor%

Die Verschiebung ist notwendig, weil std::packaged_task nicht kopierbar ist. Das Abnehmen des Threads ist nur notwendig, wenn Sie nur mit der Zukunft synchronisieren möchten - andernfalls müssen Sie dem Thread explizit beitreten. Wenn Sie dies nicht tun, ruft der Destruktor des Threads einfach std::terminate() auf.

%Vor%     
Klaim 07.09.2012 15:22
quelle
11

Wie andere vorgeschlagen haben, können die Einrichtungen in <future> dafür verwendet werden. Ich widerspreche jedoch der Antwort

  

Nein, das geht nicht mit std::thread

Hier ist eine Möglichkeit, was Sie mit std::thread machen können. Es ist keineswegs der einzige Weg:

%Vor%

Dies wird portabel ausgeben:

%Vor%     
Howard Hinnant 07.09.2012 15:33
quelle
3

Hier ist ein Beispiel mit packaged_task :

%Vor%     
Pete Becker 07.09.2012 15:15
quelle