Klassen:
- Klasse
std::future
Funktionen:
- Funktion
std::async
Aufzählungstypen:
- Aufzählungstyp
enum class launch
Das Zusammenspiel zwischen der Methode std::async und Objekten
des Typs std::future wird gezeigt.
Die std::async-Methode besitzt im Wesentlichen drei Überladungen:
std::asyncmit normaler C-Funktion.std::asyncmit aufrufbarem Objekt.std::asyncmit Lambda-Objekt.
Async_01.cpp
Async_02.cpp
Async_03.cpp
In Bezug auf std::async können wir die allgemeine Aussage treffen,
dass die Funktion eine Funktion in einem separaten Thread startet,
wenn keine launch policy spezifiziert ist.
Der C++-Standard gibt jedoch nicht an, ob der Thread neu ist (std::thread)
oder aus einem Thread-Pool wiederverwendet wird.
In Bezug auf das Windows Betriebssystem können wir jedoch aus verfügbaren Quellen entnehmen,
dass das Erzeugen des Threads mit einem Aufruf von ::Concurrency::create_task erfolgt.
Diese Funktion ist Teil der Parallel Patterns Library von Microsoft.
Laut MSDN verwendet die task-Klasse den Windows ThreadPool als Scheduler!
Weitere Details finden sich in einem Artikel Implementations of std::async von Dmitry Danilov.
In den Übungen zu diesem Repository finden Sie in der dritten Aufgabe einen Vergleich zwischen dem Arbeiten mit „normalen„ Threads und solchen Threads, die aus einem Thread Pool stammen.
Es werden zwei Threads mit std::async gestartet, die beide einen Zeitstempel zurückliefern.
Sie unterscheiden sich bzgl. der verwendeten Launch Policy:
launch::async
Startet einen eigenen Thread im Hintergrund.launch::deferred
Wartet mit der Ausführung der Threadprozedur, bis der Aufrufer das Ergebnis mitgetabholen möchte. Dazu muss nicht zwingend ein separater Thread verwendet werden, die Threadprozedur kann im Kontext des aktuellen Threads ausgeführt werden.
Analysieren Sie das Beispiel im Quellcode genau! Die Ausführung des Programms lautet:
Preparing calculations ...
Now waiting for 4 seconds ...
launch::async thread done!
launch::deferred thread done!
asyncLazy evaluated after : 4.00645 seconds.
asyncEager evaluated after: 0.0006665 seconds.
Es werden vier Vertiefungen der Funktionsschablone std::async studiert:
- Parallele Ausführung mehrerer Threads - das Resultat wird mit
getabgeholt. - Parallele Ausführung mehrerer Threads - es wird nur ein Resultat (mit
getabgeholt). Welche Rolle spielt der Destruktor der beteiligtenFuture-Objekte? - Parallele Ausführung mehrerer Threads - es wird nur ein Resultat (mit
getabgeholt). Welche Rolle spielt die Launch Policy? - Parallele Ausführung eines Threads - das Resultat muss nicht zwingend
getabgeholt werden, mit der Methodewait_foran einemFuture-Objekt und dem Aufzählungstypfuture_statuskann man den Status desFuture-Objekts erfragen.
enum class future_status // names for timed wait function returns
{
ready,
timeout,
deferred
};Studieren Sie die Ausführung der vier Beispiele genau!
Ausgabe Beispiel 1:
Please wait ...
fib(40): 102334155
fib(41): 165580141
fib(42): 267914296
fib(43): 433494437
Done.
Ausgabe Beispiel 2:
Please wait ...
fib(40): 102334155
Done. // <=== ???
Ausgabe Beispiel 3:
Preparing calculations ...
Retrieve single result of fib(42):
fib(42): 267914296
Done. // <=== ???
Ausgabe Beispiel 4:
Calculation with wait:
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
not yet calculated ...
fib(40): 102334155
Elapsed time in milliseconds = 5655 [milliseconds]