2016-04-24 12 views
1

Ich möchte einige system Aufrufe parallel ausführen, aber auch wenn ich f1.get() aufrufen die Coping in den Zeilen unten findet nicht statt. Was ist falsch an diesem Code?Zukunft wird nicht ausgeführt, auch wenn get() heißt

auto f1 = std::async(system, string("cp a b").c_str()); 
f1.get(); // there is still no file "b". 

Anmerkung: Ich schrieb string(...).c_str() weil in meinem realen Code, den ich mit dem Argument zusammen aus verschiedenen Saiten setzen.

+3

'string (" cp a b "). C_str()' wird einen baumelnden Zeiger an "system" übergeben, wenn es ausgeführt wird. – melak47

+0

Auf der anderen Seite bleiben String-Literale am Leben. 'std :: async (System," cp a b ")' –

+0

Und der Code scheint zu funktionieren. Vielleicht gibt es ein paar Probleme mit der Art und Weise, wie Argumente für "System" konstruiert werden. –

Antwort

2

Der std::string Ihren Befehl enthält, ist ein temporäres Objekt und wird nur bis zum Ende des std::async Ruf leben, so durch die Zeit system aufgerufen wird, kann der Zeiger auf gelöschte Speicher beziehen, die Arbeit passieren kann, oder es könnte lesen rm -rf/--no-preserve-root - es ist undefiniertes Verhalten.

Sie müssen sicherstellen, dass das String-Objekt lange genug lebt. In Ihrem Beispiel ist das einfach, aber es ist nicht immer so, wenn Sie asynchrone Operationen starten.

C++ 11 Lambda-Ausdrücke geben uns eine schöne Möglichkeit, für genau die Zeichenfolge zu speichern, solange wir sie brauchen:

std::string command = "cp main.cpp b"; 

auto f1 = std::async(std::launch::async, 
    [command]{ // copy command into the closure 
     std::system(command.c_str()); 
    } 
); 

Beachten Sie auch, dass Sie die async Start Politik nicht angefordert haben, Ihre so Funktion kann synchron noch ausgeführt werden.

Seitennotiz: Sie sollten in Erwägung ziehen, etwas wie POCO's Process zu verwenden, wenn Sie externe Prozesse starten und die Ausgabe erfassen, den Status beenden und so weiter.