QPromise Class

template <typename T> class QPromise

QPromise クラスは、QFuture によってアクセスされる計算結果を保存する方法を提供します。さらに...

Header: #include <QPromise>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
Since: Qt 6.0

注意:このクラスの関数はすべてスレッドセーフです。

パブリック関数

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)

詳細説明

QPromiseは、ユーザー定義の計算の進捗と結果を非同期でQFuture 。この通信が機能するためには、QFuture が QPromise によって構築されている必要があります。

きめ細かい制御が必要な場合や、QFuture に付随する高レベルの通信プリミティブで十分な場合は、Qt Concurrentフレームワークの代替として QPromise ベースのワークロードを使用できます。

プロミスと未来のコラボレーションの最も単純なケースは、単一の結果通信です:

    QPromise<int> promise;
    QFuture<int> future = promise.future();

    QScopedPointer<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は移動専用のオブジェクトです。この振る舞いは、プロミスが破棄されるたびに関連するfutureオブジェクトに通知され、結果が利用可能になるまで永遠に待つことがないようにするのに役立ちます。しかし、同じプロミスを使用して異なるスレッドから結果を報告したい場合、これは不便です。今のところそのための特別な方法はありませんが、スマート・ポインタやロー・ポインタ/参照の使用など、既知のメカニズムが存在します。QSharedPointer は、プロミスをコピーして複数の場所で同時に使用したい場合のデフォルトの良い選択です。未加工のポインタや参照は、ある意味簡単で、(リソース管理をする必要がないので)おそらく性能も良いのですが、ダングリングにつながる可能性があります。

プロミスを複数のスレッドで使用する例を示します:

    QSharedPointer<QPromise<int>> sharedPromise(new QPromise<int>());
    QFuture<int> future = sharedPromise->future();

    // ...

    sharedPromise->start();

    // here, QPromise is shared between threads via a smart pointer
    QScopedPointer<QThread> threads[] = {
        QScopedPointer<QThread>(QThread::create([] (auto sharedPromise) {
            sharedPromise->addResult(0, 0);  // adds value 0 by index 0
        }, sharedPromise)),
        QScopedPointer<QThread>(QThread::create([] (auto sharedPromise) {
            sharedPromise->addResult(-1, 1);  // adds value -1 by index 1
        }, sharedPromise)),
        QScopedPointer<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();

QFutureも参照

メンバ関数ドキュメント

bool QPromise::addResult(T &&result, int index = -1)

bool QPromise::addResult(const T &result, int index = -1)

と同じ。

emplaceResultAt(index, result);            // first overload
emplaceResultAt(index, std::move(result)); // second overload

または、index == -1 (デフォルト)の場合

emplaceResult(result);            // first overload
emplaceResult(std::move(result)); // second overload

emplaceResultAt()、emplaceResult()、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)

index の位置 (emplaceResultAt()) またはコレクションの末尾 (emplaceResult()) に、args... から構築された結果を内部結果コレクションに追加します。

結果がコレクションに追加されると、true を返します。

このプロミスがキャンセルされた状態または終了した状態のとき、または結果が拒否されたときにfalse を返します。addResult() は、同じインデックスに格納されている別の結果がすでにコレクションにある場合、結果の追加を拒否します。

これらの関数は、Targs....

QFuture::resultAt() を呼び出すと、特定のインデックスで結果を取得できます。

注意: 任意のインデックスを指定して、そのインデックスでの結果を要求することも可能です。しかし、QFuture メソッドの中には、連続的な結果で動作するものがある。たとえば、QFuture::resultCount() やQFuture::const_iterator を使用する反復アプローチなどである。 インデックスのギャップがあるかどうかを考えずに、利用可能なすべての結果を取得するには、QFuture::results() を使用する。

この関数はQt 6.6で導入されました。

addResult() やaddResults()も参照して ください。

QPromise::QPromise()

デフォルトの状態を持つ QPromise を構築します。

QPromise::QPromise(QPromise<T> &&other)

Move はother から新しい QPromise を構築します。

operator=()も参照してください

QPromise::~QPromise()

約束を破棄します。

注意: ユーザーが事前にfinish() を呼び出さない限り、プロミスは破棄時に暗黙的にキャンセル状態に遷移します。

[since 6.6] bool QPromise::addResults(const QList<T> &results)

内部結果コレクションの最後にresults を追加します。

results がコレクションに追加されるとtrue を返します。

このプロミスがキャンセルされた状態または終了した状態のとき、false を返します。

これはaddResult() をループするよりも効率的である。なぜなら、addResult() を個別に呼び出す場合のように、results に含まれる要素ごとに通知されるのではなく、addResults() を呼び出すごとに、関連するフューチャーに一度だけ通知されるからである。しかし、各要素の計算に時間がかかると、受信側のコード(フューチャー)は、すべての結果が報告されるまで処理を進めることができないため、連続する要素の計算が比較的高速な場合にのみ、この関数を使用します。

この関数は Qt 6.6 で導入されました。

addResult()も参照してください

void QPromise::finish()

計算が終了したことを報告します。終了すると、addResult() を呼び出しても、新しい結果は追加されません。このメソッドは、start() に付随します。

QFuture::isFinished()、QFuture::waitForFinished()、start()も参照

QFuture<T> QPromise::future() const

このプロミスに関連付けられた未来を返します。

bool QPromise::isCanceled() const

計算がQFuture::cancel() 関数でキャンセルされたかどうかを返します。返された値true は、計算を終了してfinish() を呼び出す必要があることを示します。

注意: キャンセル後も、現在利用可能な結果には future でアクセスできますが、addResult() を呼び出したときに新しい結果が追加されることはありません。

void QPromise::setException(const QException &e)

例外e を計算結果に設定します。

注意 : 計算の実行中に設定できる例外は 1 つまでです。

注意 : このメソッドは、QFuture::cancel() またはfinish() の後には使用しないでください。

isCanceled()も参照

void QPromise::setException(std::__exception_ptr::exception_ptr e)

これはオーバーロードされた関数です。

void QPromise::setProgressRange(int minimum, int maximum)

計算の進行範囲をminimum からmaximum の間に設定する。

maximumminimum より小さい場合、minimum が唯一の合法的な値となる。

進捗値はminimum にリセットされる。

進捗範囲の使用は、setProgressRange(0, 0)を使って無効にすることができる。この場合、進捗値も0にリセットされる。

QFuture::progressMinimum()、QFuture::progressMaximum()、QFuture::progressValue()も参照

void QPromise::setProgressValue(int progressValue)

計算の進行値をprogressValue に設定します。 進行値をインクリメントすることのみが可能です。これは、setProgressValueAndText(progressValue, QString()) を呼び出すための便利なメソッドです。

progressValue が進捗範囲から外れた場合、このメソッドは何の効果もない。

QFuture::progressValue() およびsetProgressRange()も参照してください

void QPromise::setProgressValueAndText(int progressValue, const QString &progressText)

計算の進行値と進行テキストをそれぞれprogressValueprogressText に設定する。進捗値のみをインクリメントすることも可能です。

注意: この関数は、プロミスがキャンセルされた状態または終了した状態の場合、何の効果もありません。

QFuture::progressValue()、QFuture::progressText()、QFuture::cancel()、finish()も参照

void QPromise::start()

計算が開始されたことを報告する。QFuture のメソッドはこの情報に依存しているので、このメソッドを呼び出すことは計算の開始を示すために重要です。

注意: start()が新しく作成されたスレッドから呼び出される場合は、特に注意が必要である。このような場合、スレッドスケジューリングの実装の詳細により、呼び出しが当然遅れる可能性がある。

QFuture::isStarted()、QFuture::waitForFinished()、finish()も参照のこと

void QPromise::suspendIfRequested()

条件付きで現在のスレッドの実行を一時停止し、QFuture の対応するメソッドによって再開またはキャンセルされるまで待機する。このメソッドは、QFuture::suspend() または他の関連するメソッドによって計算の一時停止が要求されない限り、ブロックされない。実行が一時停止されたことを確認したい場合は、QFuture::isSuspended() を使用します。

注意: 複数のスレッドで同じプロミスを使用する場合、QFuture::isSuspended() は、プロミスを持つ少なくとも1つのスレッドが一時停止するとすぐにtrue になります。

以下のコード・スニペットは、サスペンド・メカニズムの使用法を示している:

    // Create promise and future
    QPromise<int> promise;
    QFuture<int> future = promise.future();

    promise.start();
    // Start a computation thread that supports suspension and cancellation
    QScopedPointer<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() は、関連するプロミスにサスペンドを要求する:

    future.suspend();

QFuture::isSuspended() がtrue になった後、中間結果を得ることができる:

    future.resultCount();  // returns some number between 0 and 100
    for (int i = 0; i < future.resultCount(); ++i) {
        // process results available before suspension
    }

中断されると、待機中の計算を再開またはキャンセルできる:

    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

QFuture::resume(),QFuture::cancel(),QFuture::setSuspended(),QFuture::toggleSuspended()も参照

[noexcept] void QPromise::swap(QPromise<T> &other)

プロミスother をこのプロミスと交換する。この操作は非常に速く、失敗することはない。

[noexcept] QPromise<T> &QPromise::operator=(QPromise<T> &&other)

Move はother をこのプロミスに代入し、このプロミスへの参照を返します。

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。