std::promise
| Definiert im Header <future> |
||
| template< class R > class promise; |
(1) | (seit C++11) |
| template< class R > class promise<R&>; |
(2) | (seit C++11) |
| template<> class promise<void>; |
(3) | (seit C++11) |
Die Klassenvorlage std::promise bietet eine Einrichtung, um einen Wert oder eine Ausnahme zu speichern, der später asynchron über ein std::future-Objekt abgerufen wird, das vom std::promise-Objekt erstellt wurde. Beachten Sie, dass das std::promise-Objekt nur einmal verwendet werden soll.
Jede promise ist mit einem *gemeinsamen Zustand* verbunden, der einige Zustandsinformationen und ein *Ergebnis* enthält, das möglicherweise noch nicht ausgewertet wurde, zu einem Wert (möglicherweise void) ausgewertet wurde oder zu einer Ausnahme ausgewertet wurde. Eine promise kann drei Dinge mit dem gemeinsamen Zustand tun:
- bereit machen: Die promise speichert das Ergebnis oder die Ausnahme im gemeinsamen Zustand. Markiert den Zustand als bereit und entsperrt jeden Thread, der auf eine mit dem gemeinsamen Zustand verbundene Future wartet.
- freigeben: Die promise gibt ihre Referenz auf den gemeinsamen Zustand auf. Wenn dies die letzte solche Referenz war, wird der gemeinsame Zustand zerstört. Sofern es sich nicht um einen gemeinsamen Zustand handelt, der von std::async erstellt wurde und noch nicht bereit ist, blockiert diese Operation nicht.
- aufgeben: Die promise speichert die Ausnahme vom Typ std::future_error mit dem Fehlercode std::future_errc::broken_promise, macht den gemeinsamen Zustand *bereit* und gibt ihn dann *frei*.
Die promise ist das "Push"-Ende des Promise-Future-Kommunikationskanals: Die Operation, die einen Wert im gemeinsamen Zustand speichert, *synchronisiert sich mit* (wie in std::memory_order definiert) der erfolgreichen Rückgabe von jeder Funktion, die auf dem gemeinsamen Zustand wartet (wie z. B. std::future::get). Gleichzeitiger Zugriff auf denselben gemeinsamen Zustand kann sonst zu Konflikten führen: Beispielsweise müssen mehrere Aufrufer von std::shared_future::get entweder alle schreibgeschützt sein oder eine externe Synchronisation bereitstellen.
Inhalt |
[bearbeiten] Memberfunktionen
| konstruiert das promise-Objekt (public member function) | |
| destruiert das promise-Objekt (public member function) | |
| weist den gemeinsamen Zustand zu (public member function) | |
| tauscht zwei promise-Objekte (public member function) | |
Ergebnis abrufen | |
| gibt eine future zurück, die mit dem versprochenen Ergebnis verbunden ist (public member function) | |
Ergebnis setzen | |
| setzt das Ergebnis auf einen bestimmten Wert (public member function) | |
| setzt das Ergebnis auf einen bestimmten Wert und liefert die Benachrichtigung erst beim Beenden des Threads (public member function) | |
| setzt das Ergebnis, um eine Ausnahme anzuzeigen (public member function) | |
| setzt das Ergebnis, um eine Ausnahme anzuzeigen, und liefert die Benachrichtigung erst beim Beenden des Threads (public member function) | |
[bearbeiten] Nicht-Member-Funktionen
| (C++11) |
spezialisiert den Algorithmus std::swap (Funktionstemplates) |
[bearbeiten] Hilfsklassen
| spezialisiert das std::uses_allocator Typ-Trait (Klassentemplate-Spezialisierung) |
[bearbeiten] Beispiel
Dieses Beispiel zeigt, wie promise<int> als Signale zwischen Threads verwendet werden kann.
#include <chrono> #include <future> #include <iostream> #include <numeric> #include <thread> #include <vector> void accumulate(std::vector<int>::iterator first, std::vector<int>::iterator last, std::promise<int> accumulate_promise) { int sum = std::accumulate(first, last, 0); accumulate_promise.set_value(sum); // Notify future } void do_work(std::promise<void> barrier) { std::this_thread::sleep_for(std::chrono::seconds(1)); barrier.set_value(); } int main() { // Demonstrate using promise<int> to transmit a result between threads. std::vector<int> numbers = {1, 2, 3, 4, 5, 6}; std::promise<int> accumulate_promise; std::future<int> accumulate_future = accumulate_promise.get_future(); std::thread work_thread(accumulate, numbers.begin(), numbers.end(), std::move(accumulate_promise)); // future::get() will wait until the future has a valid result and retrieves it. // Calling wait() before get() is not needed // accumulate_future.wait(); // wait for result std::cout << "result=" << accumulate_future.get() << '\n'; work_thread.join(); // wait for thread completion // Demonstrate using promise<void> to signal state between threads. std::promise<void> barrier; std::future<void> barrier_future = barrier.get_future(); std::thread new_work_thread(do_work, std::move(barrier)); barrier_future.wait(); new_work_thread.join(); }
Ausgabe
result=21