QPromise Class
template <typename T> class QPromiseQPromise クラスは、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(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() は、同じインデックスに格納されている別の結果がすでにコレクションにある場合、結果の追加を拒否します。
これらの関数は、T
がargs....
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 の間に設定する。
maximum がminimum より小さい場合、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)
計算の進行値と進行テキストをそれぞれprogressValue とprogressText に設定する。進捗値のみをインクリメントすることも可能です。
注意: この関数は、プロミスがキャンセルされた状態または終了した状態の場合、何の効果もありません。
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.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。