QPromise Class
template <typename T> class QPromiseDie Klasse QPromise bietet eine Möglichkeit, Berechnungsergebnisse zu speichern, auf die QFuture zugreifen kann. Mehr...
Kopfzeile: | #include <QPromise> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
Seit: | Qt 6.0 |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QPromise ist Teil der Threading-Klassen.
Hinweis: Alle Funktionen in dieser Klasse sind thread-sicher.
Öffentliche Funktionen
QPromise() | |
QPromise(QPromise<T> &&other) | |
~QPromise() | |
bool | addResult(T &&result, int index = -1) |
bool | addResult(const T &result, int index = -1) |
(since 6.6) bool | addResults(const QList<T> &results) |
(since 6.6) bool | emplaceResult(Args &&... args) |
(since 6.6) bool | emplaceResultAt(int index, Args &&... args) |
void | finish() |
QFuture<T> | future() const |
bool | isCanceled() const |
void | setException(const QException &e) |
void | setException(std::__exception_ptr::exception_ptr e) |
void | setProgressRange(int minimum, int maximum) |
void | setProgressValue(int progressValue) |
void | setProgressValueAndText(int progressValue, const QString &progressText) |
void | start() |
void | suspendIfRequested() |
void | swap(QPromise<T> &other) |
QPromise<T> & | operator=(QPromise<T> &&other) |
Detaillierte Beschreibung
QPromise bietet eine einfache Möglichkeit, den Fortschritt und die Ergebnisse einer benutzerdefinierten Berechnung auf asynchrone Weise an QFuture zu kommunizieren. Damit die Kommunikation funktioniert, muss QFuture von QPromise erstellt werden.
Sie können QPromise-basierte Workloads als Alternative zu Qt Concurrent Framework verwenden, wenn eine feinkörnige Steuerung erforderlich ist oder eine primitive Kommunikation auf hoher Ebene zur Begleitung von QFuture ausreicht.
Der einfachste Fall der Zusammenarbeit von Promise und Future wäre eine einzelne Ergebniskommunikation:
QPromise<int> promise; QFuture<int> future = promise.future(); const std::unique_ptr<QThread> thread(QThread::create([] (QPromise<int> promise) { promise.start(); // notifies QFuture that the computation is started promise.addResult(42); promise.finish(); // notifies QFuture that the computation is finished }, std::move(promise))); thread->start(); future.waitForFinished(); // blocks until QPromise::finish is called future.result(); // returns 42
QPromise ist vom Design her ein reines Bewegungsobjekt. Dieses Verhalten hilft sicherzustellen, dass das zugehörige Future-Objekt benachrichtigt wird, wenn das Versprechen zerstört wird, und nicht ewig auf die Verfügbarkeit der Ergebnisse wartet. Dies ist jedoch unpraktisch, wenn man dasselbe Versprechen verwenden möchte, um Ergebnisse aus verschiedenen Threads zu melden. Es gibt derzeit keine spezielle Möglichkeit, dies zu tun, aber es gibt bekannte Mechanismen, wie die Verwendung von intelligenten Zeigern oder rohen Zeigern/Referenzen. QSharedPointer ist eine gute Standardwahl, wenn Sie Ihr Versprechen kopieren und an mehreren Stellen gleichzeitig verwenden möchten. Rohe Zeiger oder Referenzen sind in gewissem Sinne einfacher und funktionieren wahrscheinlich besser (da keine Ressourcenverwaltung erforderlich ist), können aber zu einem "Dangling" führen.
Hier ist ein Beispiel dafür, wie ein Versprechen in mehreren Threads verwendet werden kann:
const auto sharedPromise = std::make_shared<QPromise<int>>(); QFuture<int> future = sharedPromise->future(); // ... sharedPromise->start(); // here, QPromise is shared between threads via a smart pointer const std::unique_ptr<QThread> threads[] = { std::unique_ptr<QThread>(QThread::create([] (auto sharedPromise) { sharedPromise->addResult(0, 0); // adds value 0 by index 0 }, sharedPromise)), std::unique_ptr<QThread>(QThread::create([] (auto sharedPromise) { sharedPromise->addResult(-1, 1); // adds value -1 by index 1 }, sharedPromise)), std::unique_ptr<QThread>(QThread::create([] (auto sharedPromise) { sharedPromise->addResult(-2, 2); // adds value -2 by index 2 }, sharedPromise)), // ... }; // start all threads for (auto& t : threads) t->start(); // ... future.resultAt(0); // waits until result at index 0 becomes available. returns value 0 future.resultAt(1); // waits until result at index 1 becomes available. returns value -1 future.resultAt(2); // waits until result at index 2 becomes available. returns value -2 sharedPromise->finish();
Siehe auch QFuture.
Dokumentation der Mitgliedsfunktionen
bool QPromise::addResult(T &&result, int index = -1)
bool QPromise::addResult(const T &result, int index = -1)
Gleich wie
emplaceResultAt(index, result); // first overload emplaceResultAt(index, std::move(result)); // second overload
oder, falls index == -1
(die Voreinstellung)
emplaceResult(result); // first overload emplaceResult(std::move(result)); // second overload
Siehe auch emplaceResultAt(), emplaceResult(), und addResults().
[since 6.6]
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise::emplaceResult(Args &&... args)
[since 6.6]
template <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise::emplaceResultAt(int index, Args &&... args)
Fügt ein aus args... konstruiertes Ergebnis der internen Ergebnissammlung an der Position index (emplaceResultAt()) oder am Ende der Sammlung (emplaceResult()) hinzu.
Gibt true
zurück, wenn das Ergebnis zur Sammlung hinzugefügt wurde.
Gibt false
zurück, wenn sich dieses Versprechen in einem abgebrochenen oder beendeten Zustand befindet oder wenn das Ergebnis abgelehnt wurde. addResult() lehnt das Hinzufügen eines Ergebnisses ab, wenn bereits ein anderes Ergebnis in der Sammlung mit demselben Index gespeichert ist.
Diese Funktionen nehmen nur an Überlastauflösungen teil, wenn T
aus args....
Sie können ein Ergebnis mit einem bestimmten Index erhalten, indem Sie QFuture::resultAt() aufrufen.
Hinweis: Es ist möglich, einen beliebigen Index anzugeben und ein Ergebnis an diesem Index anzufordern. Einige Methoden von QFuture arbeiten jedoch mit kontinuierlichen Ergebnissen. Zum Beispiel iterative Ansätze, die QFuture::resultCount() oder QFuture::const_iterator verwenden. Um alle verfügbaren Ergebnisse zu erhalten, ohne zu berücksichtigen, ob es Indexlücken gibt oder nicht, verwenden Sie QFuture::results().
Diese Funktion wurde in Qt 6.6 eingeführt.
Siehe auch addResult() und addResults().
QPromise::QPromise()
Konstruiert ein QPromise mit einem Standardzustand.
QPromise::QPromise(QPromise<T> &&other)
Move konstruiert ein neues QPromise aus other.
Siehe auch operator=().
QPromise::~QPromise()
Zerstört das Versprechen.
Hinweis: Das Versprechen geht bei der Zerstörung implizit in einen abgebrochenen Zustand über, es sei denn, finish() wird vorher vom Benutzer aufgerufen.
[since 6.6]
bool QPromise::addResults(const QList<T> &results)
Fügt results am Ende der internen Ergebnissammlung hinzu.
Gibt true
zurück, wenn results der Sammlung hinzugefügt wird.
Gibt false
zurück, wenn sich dieses Versprechen im Zustand "abgebrochen" oder "beendet" befindet.
Dies ist effizienter als eine Schleife über addResult(), da die zugehörigen Futures nur einmal pro addResults()-Aufruf benachrichtigt werden, anstatt einmal pro Element, das in results enthalten ist, wie es bei einzelnen addResult()-Aufrufen der Fall wäre. Aber wenn die Berechnung jedes Elements Zeit in Anspruch nimmt, dann kann der Code auf der Empfängerseite (future) nicht vorankommen, bis alle Ergebnisse gemeldet sind, also verwenden Sie diese Funktion nur, wenn die Berechnung aufeinanderfolgender Elemente relativ schnell ist.
Diese Funktion wurde in Qt 6.6 eingeführt.
Siehe auch addResult().
void QPromise::finish()
Meldet, dass die Berechnung abgeschlossen ist. Sobald die Berechnung abgeschlossen ist, werden beim Aufruf von addResult() keine neuen Ergebnisse mehr hinzugefügt. Diese Methode wird von start() begleitet.
Siehe auch QFuture::isFinished(), QFuture::waitForFinished(), und start().
QFuture<T> QPromise::future() const
Gibt einen Future zurück, der mit diesem Versprechen verknüpft ist.
bool QPromise::isCanceled() const
Gibt zurück, ob die Berechnung mit der Funktion QFuture::cancel() abgebrochen wurde. Der Rückgabewert true
bedeutet, dass die Berechnung beendet und finish() aufgerufen werden sollte.
Hinweis: Nach dem Abbruch kann auf aktuell verfügbare Ergebnisse weiterhin mit einem future zugegriffen werden, aber neue Ergebnisse werden beim Aufruf von addResult() nicht hinzugefügt.
void QPromise::setException(const QException &e)
Legt die Ausnahme e als Ergebnis der Berechnung fest.
Hinweis: Sie können während der gesamten Berechnungsausführung höchstens eine Ausnahme setzen.
Hinweis: Diese Methode hat keine Auswirkung nach QFuture::cancel() oder finish().
Siehe auch isCanceled().
void QPromise::setException(std::__exception_ptr::exception_ptr e)
Dies ist eine überladene Funktion.
void QPromise::setProgressRange(int minimum, int maximum)
Legt den Fortschrittsbereich der Berechnung auf einen Wert zwischen minimum und maximum fest.
Wenn maximum kleiner als minimum ist, ist minimum der einzig zulässige Wert.
Der Fortschrittswert wird auf den Wert minimum zurückgesetzt.
Die Verwendung des Fortschrittsbereichs kann mit setProgressRange(0, 0) deaktiviert werden. In diesem Fall wird der Fortschrittswert ebenfalls auf 0 zurückgesetzt.
Siehe auch QFuture::progressMinimum(), QFuture::progressMaximum(), und QFuture::progressValue().
void QPromise::setProgressValue(int progressValue)
Setzt den Fortschrittswert der Berechnung auf progressValue. Es ist möglich, den Fortschrittswert nur zu erhöhen. Dies ist eine Komfortmethode für den Aufruf von setProgressValueAndText(progressValue, QString()).
Falls der progressValue aus dem Fortschrittsbereich herausfällt, hat diese Methode keine Wirkung.
Siehe auch QFuture::progressValue() und setProgressRange().
void QPromise::setProgressValueAndText(int progressValue, const QString &progressText)
Setzt den Fortschrittswert und den Fortschrittstext der Berechnung auf progressValue bzw. progressText. Es ist möglich, nur den Fortschrittswert zu erhöhen.
Hinweis: Diese Funktion hat keine Wirkung, wenn sich das Versprechen im Zustand "abgebrochen" oder "beendet" befindet.
Siehe auch QFuture::progressValue(), QFuture::progressText(), QFuture::cancel(), und finish().
void QPromise::start()
Meldet, dass die Berechnung gestartet ist. Der Aufruf dieser Methode ist wichtig, um den Beginn der Berechnung anzugeben, da die Methoden von QFuture auf diese Information angewiesen sind.
Hinweis: Besondere Aufmerksamkeit ist erforderlich, wenn start() von einem neu erstellten Thread aufgerufen wird. In einem solchen Fall kann sich der Aufruf aufgrund der Implementierungsdetails des Thread-Schedulings natürlich verzögern.
Siehe auch QFuture::isStarted(), QFuture::waitForFinished(), und finish().
void QPromise::suspendIfRequested()
Setzt den aktuellen Ausführungsstrang bedingt aus und wartet, bis er durch die entsprechenden Methoden von QFuture wieder aufgenommen oder abgebrochen wird. Diese Methode blockiert nicht, es sei denn, die Berechnung wird durch QFuture::suspend() oder eine andere verwandte Methode angefordert, um ausgesetzt zu werden. Wenn Sie überprüfen wollen, ob die Ausführung unterbrochen wurde, verwenden Sie QFuture::isSuspended().
Hinweis: Bei Verwendung desselben Versprechens in mehreren Threads wird QFuture::isSuspended() zu true
, sobald mindestens ein Thread mit dem Versprechen unterbrochen wird.
Die folgenden Codeschnipsel zeigen die Verwendung des Aussetzungsmechanismus:
// Create promise and future QPromise<int> promise; QFuture<int> future = promise.future(); promise.start(); // Start a computation thread that supports suspension and cancellation const std::unique_ptr<QThread> thread(QThread::create([] (QPromise<int> promise) { for (int i = 0; i < 100; ++i) { promise.addResult(i); promise.suspendIfRequested(); // support suspension if (promise.isCanceled()) // support cancellation break; } promise.finish(); }, std::move(promise))); thread->start();
QFuture::suspend() fordert das zugehörige Versprechen zum Aussetzen auf:
future.suspend();
Nachdem QFuture::isSuspended() zu true
wird, können Sie Zwischenergebnisse erhalten:
future.resultCount(); // returns some number between 0 and 100 for (int i = 0; i < future.resultCount(); ++i) { // process results available before suspension }
Nach der Aussetzung können Sie die anstehende Berechnung fortsetzen oder abbrechen:
future.resume(); // resumes computation, this call will unblock the promise // alternatively, call future.cancel() to stop the computation future.waitForFinished(); future.results(); // returns all computation results - array of values from 0 to 99
Siehe auch QFuture::resume(), QFuture::cancel(), QFuture::setSuspended(), und QFuture::toggleSuspended().
[noexcept]
void QPromise::swap(QPromise<T> &other)
Tauscht dieses Versprechen mit other aus. Dieser Vorgang ist sehr schnell und schlägt nie fehl.
[noexcept]
QPromise<T> &QPromise::operator=(QPromise<T> &&other)
Move weist other diesem Versprechen zu und gibt einen Verweis auf dieses Versprechen zurück.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.