Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

C++: Multithreading

std::promise und std::future

Testen Sie unsere 2016 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
std::promise und std::future geben die volle Kontrolle über die Task.
05:40

Transkript

In dieser Lektion will ich Ihnen Promise und Future genau vorstellen. Insbesondere will ich Ihnen das Interface dieser zwei Datentypen genau vorstellen. Promise und Future - die geben die volle Kontrolle über die Task. Jetzt das Interface eines Promise. Was können Sie mit einem Promise alles tun? Sie können Promises swapen, also austauschen. Natürlich können Sie aus dem Promise den Future erzeugen, durch den Aufruf: get_future. Mit set_value setzt der Promise sein Ergebnis in den gemeinsamen Zustand, den der Future dann abfragen kann. Durch set_exception setzt er dann die Ausnahmen. Und da gibt's noch zwei Variationen dazu: Durch set_value_at_thread_exit und set_exception_at_thread_exit wird der Wert zwar gesetzt, aber er steht erst zur Verfügung, wenn der Promise fertig ist. Nun zum Future. Der Future besitzt eine Funktion fut.share. Damit können Sie aus einem Future einen Shared_future machen. Das heißt, normal besteht zwischen Promise und Future eine "Eins Zu Eins"-Beziehung. Es ist aber auch möglich, dass ein Promise mehrere Futures auf einmal bedient. Das sind aber dann nicht Future, das sind sogenannte shared_future. Shared_future unterscheiden sich in unserem Fall von den Futures, dass Shared_future die Copy Semantic unterstützen. Das heißt, Shared_future können Sie kopieren. Den Future können Sie nicht kopieren, den können Sie nur verschieben: der unterstützt also nur die Move Semantic. Mit fut.get fragen Sie den Wert von Ihrem Promise ab. Durch fut.valide fragen Sie ab, ob der Promise Shared den Wert in den gemeinsamen Zustand geschrieben hat. Durch fut.wait warten Sie, bis der gemeinsame Zustand vorliegt. Fut.wait ist das Interface, das Ihnen hilft, Bedingungsvariablen durch Futures zu ersetzen. Dann gibt's noch die zwei Variationen: fut.wait_for, fut.wait_until Mit bekannter Manier: wait_for - warten Sie eine Zeitdauer, wait_until - warten Sie bis zu einem Zeitpunkt. Zum Abschluss noch: fut.wait erlaubt es Ihnen, den Future mit dem Promise zu synchronisieren. Das will ich gerne explizit nochmal betonen. Und Promise und Future sind in den meisten Fällen Bedingungsvariablen vorzuziehen, weil sie viel einfacher richtig zu verwenden sind. Nun aber zum Beispiel: In dem Beispiel verwende ich zwei Promise: den prodPromise, der soll ein Produkt berechnen, als Ergebnis 'nen Int zu geben, Int-Typ. Den divPromise, der soll zwei Werte teilen und auch einen Int-Wert zurückgeben. Dann nehme ich diesen prodPromise und erzeuge mir daraus den get_future. Damit habe ich es prodResult, da bei get_future, der das Ergebnis meiner Multiplikation abfragen kann. Der erwartet natürlich auch in "Int", weil der in Int produziert. Dann habe ich noch divResult. Das ist der Future, den ich verwende, um das Ergebnis der Division abzufragen. Jetzt verschiebe ich den prodPromise in einen Thread. Da muss ich aber bisschen ausholen. Hier starte ich den Thread, der nennt sich prodThread, weil der multiplizieren soll. In diesem Thread verwende ich die Funktion "product". Und die product-Funktion benötigt zwei Argumente: sie benötigt einen Promise, und sie benötigt die Argumente a und b: eben die zwei Zahlen, die es zu multiplizieren gilt. Jetzt schau ich mir mit Ihnen die product-Funktion an. Die habe ich hier oben: die product-Funktion erwartet einen intPromise per rvalue Reference. Hier brauche ich eine rvalue Reference, weil ich den prodPromise verschiebe. Dazu benötige ich eine rvalue Preference und die zwei Argumente a und b. Was tut der Promise? Relativ wenig… Der gibt das Ergebnis von a mal b zurück, durch den Aufruf: set_value. So ähnlich geht der divPromise vor: hier, in diesem Fall verwende ich aber keine Funktion. In diesem Fall verwende ich ein Funktionsobjekt. Hier Div ist 'ne Klasse. Für die Klasse habe ich den Call-Operator überladen. Und der Operator erwartet per rvalue Reference intPromise und zwei Argumente: a und b. Was machte er? Er teilt a durch b, seinem Namen entsprechend. Ja, das war's fast schon. Jetzt müssen die Future noch ihre Werte abholen. prodResult.get holt das Ergebnis der Multiplikation, divResult - das Ergebnis der Division ab. Und hier, weil ich zwei Thread gestartet hab, muss ich sie natürlich joinen, weil der Zeugerthread muss natürlich auf seine Kinder warten. Jetzt führe ich das Programm nur aus. Ich denke, das ist nicht zu spannend, das könnten wir grad im Kopf berechnen. 20 mal 10 ist 200. Und 20 geteilt durch 10 ist 2. Entscheidend ist, dass das Ergebnis in einem anderen Thread berechnet wurde, und durch den future.get-Aufruf, bzw. den prodResult.get- oder divResult.get-Aufruf abgeholt wurde. Ich dieser Lektion habe ich Ihnen die Details zu Promise und Future vorgestellt. Ich habe insbesondere das reichhaltige Interface von Standard-Promise und Standard-Future dargestellt.

C++: Multithreading

Lernen Sie die High-Level Threading-Schnittstelle in C++ kennenb und nutzen, die Sie in Form von Threads, Tasks, Locks und Bedingungsvariablen zur Anwendung bringen.

2 Std. 40 min (39 Videos)
Derzeit sind keine Feedbacks vorhanden...
 
Software:
Exklusiv für Abo-Kunden
Erscheinungsdatum:16.08.2016

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!