2016-07-11 18 views
0

Ich möchte eine Funktion in C++ parallel aufrufen, die einige Zeit wartet und einige Aufgaben ausführt. Aber ich möchte nicht, dass der Ausführungsfluss auf die Funktion wartet. Ich dachte über die Verwendung von Pthread auf einfache Weise nach, aber ich muss wieder warten bis es wieder da ist!Eine Funktion parallel aufrufen C++

void A_Function() 
{ 
/* Call a function which waits for some time and then perform some tasks */ 

/* Do not wait for the above function to return and continue performing the background tasks */ 
} 

Hinweis: Wenn ich die Funktion parallel dann im nächsten Zyklus nicht die Hintergrundaufgaben ausführen, während Aufruf, wird die Funktion mir nicht korrekte Ausgabe geben.

Vielen Dank im Voraus.

+3

Klingt wie ein Job für 'std :: future'. –

+0

Ich verstehe das Problem mit Pthreads nicht? –

+0

Es gibt kein Problem mit Pthread, wenn das das Problem löst. Ich weiß nicht viel über PThreads. Was ich jetzt mache ist, einen einzelnen Thread zu erstellen und diese Funktion aufzurufen. Aber ich muss pthread_join() irgendwann richtig machen? Aber ich kann die Hintergrundaufgaben nicht bis pthread_join() blockieren. –

Antwort

1

Verwenden Sie eine std::future, um eine std::async Aufgabe zu packen. Warten Sie auf die Zukunft an der Spitze Ihrer Funktion, um sicherzustellen, dass sie vor der nächsten Iteration abgeschlossen ist, da Sie angegeben haben, dass die nächste Iteration von der Ausführung dieser Hintergrundaufgabe abhängt.

Im folgenden Beispiel mache ich die Hintergrundaufgabe zu einem einfachen atomaren Inkrement eines Zählers, und die Vordergrundaufgabe gibt nur den Zählerwert zurück. Dies dient nur zur Veranschaulichung!

#include <iostream> 
#include <future> 
#include <thread> 

class Foo { 
public: 
    Foo() : counter_(0) {} 

    std::pair<int, std::future<void>> a_function(std::future<void>& f) { 
     // Ensure that the background task from the previous iteration 
     // has completed 
     f.wait(); 

     // Set the task for the next iteration 
     std::future<void> fut = std::async(std::launch::async, 
             &Foo::background_task, this); 

     // Do some work 
     int value = counter_.load(); 

     // Return the result and the future for the next iteration 
     return std::make_pair(value, std::move(fut)); 
    } 

    void background_task() { 
     ++counter_; 
    } 

private: 
    std::atomic<int> counter_; 
}; 

int main() { 
    // Bootstrap the procedure with some empty task... 
    std::future<void> bleak = std::async(std::launch::deferred, [](){}); 

    Foo foo; 

    // Iterate... 
    for (size_t i = 0; i < 10; ++i) { 
     // Call the function 
     std::pair<int, std::future<void>> result = foo.a_function(bleak); 
     // Set the future for the next iteration 
     bleak = std::move(result.second); 

     // Do something with the result 
     std::cout << result.first << "\n"; 
    } 
} 

Live example

+0

Vielen Dank für die Antwort. Das ist etwas Neues, das ich gelernt habe. Leider bin ich gezwungen, eine Version zu verwenden, die und nicht unterstützt (nur Pthread ist verfügbar) !!! Ich denke, ich muss einen anderen Weg finden :(:(:( –

+0

'std :: future" ist auf den Threading-Primitiven der Plattform aufgebaut. In deinem Fall brauchst du nur zu überprüfen, dass der Thread fertig ist, bevor du drückst Die nächste Iteration, also der passende Platz für die ['pthread_join'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_join.html), steht an der Spitze der Funktion, bevor Berechnungen durchgeführt werden, auf die man sich verlassen kann Wenn du wirklich feuern und vergessen willst, kannst du ['pthread_detach'] (http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_detach.html) verwenden, das niemals blockieren wird. aber du wirst nicht wissen, wann es fertig ist. – Andrew

+0

Danke für den Kommentar. Ich habe das Problem mit pthread_detach bereits gelöst. Bis jetzt funktioniert es gut für mich, aber auch müssen alle Eckfälle untersuchen. Danke nochmal! –

Verwandte Themen