QPromise Class

template <typename T> class QPromise

Die 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

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.