QPromise 类
template <typename T> class QPromiseQPromise 类提供了一种将计算结果保存在 QFuture 中以供访问的方法。 更多...
头文件 | #include <QPromise> |
CMake | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake | QT += core |
自 | Qt 6.0 |
- 所有成员列表,包括继承成员
- QPromise 是 线程类 的一部分。
注意:此类中的所有函数都是 线程安全 的。
公共函数
QPromise() | |
QPromise(QPromise<T> &&other) | |
~QPromise() | |
bool | addResult(const T &result, int index = -1) |
bool | addResult(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。 要使通信工作,必须由 QPromise 创建 QFuture。
当需要精细控制或需要足够的高层通信原语来伴随 QFuture 时,可以使用 QPromise 基于的工作负载作为 Qt Concurrent 框架的替代。
承诺和未来合作的最简单案例将是单个结果通信
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 是一个只能移动的对象。这种行为有助于确保当承诺被销毁时,相关联的未来对象会被通知,并不会无限期地等待结果可用。然而,如果想要使用相同的承诺在不同线程中报告结果就很不方便。目前没有特定的方法做到这一点,但存在已知机制,例如使用智能指针或原始指针/引用。《a href="qsharedpointer.html" translate="no">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]
模板 <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise::emplaceResult(Args &&... args)
[since 6.6]
模板 <typename... Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true> bool QPromise::emplaceResultAt(int index, Args &&... args)
在内部结果集的位置 index(emplaceResultAt())或集合的末尾添加由 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<T>(&&other)
从other构建一个新的QPromise。
另请参阅operator=。
QPromise::~QPromise()
销毁承诺。
注意:除非在销毁之前用户调用 finish(),否则承诺在销毁时隐式过渡到已取消状态。
[自 6.6]
bool QPromise::addResults(const QList<T>&results)
将results添加到内部结果集合的末尾。
当结果添加到集合时返回true
。
当此承诺处于已取消或已完成状态时返回false
。
此方法比循环调用addResult()更高效,因为关联的未来将在每次调用addResults()时仅通知一次,而不是在results中的每个元素上通知一次,正如使用单独的addResult()调用的情况一样。但是,如果每个元素的计算需要时间,那么接收端(未来)的代码不能进展,直到所有结果都报告,所以只有在连续元素的计算相对较快时才使用此函数。
此函数是在 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()。
注意:在取消后,一个未来仍可以访问当前可用的结果,但在调用addResult()时不会添加任何新结果。
void QPromise::setException(const QException &e)
将异常e设置为计算的最终结果。
注意:在整个计算执行过程中,只能设置最多一个异常。
注意:此方法不得在QFuture::cancel或finish之后使用。
另请参阅isCanceled。
void QPromise::setException(std::__exception_ptr::exception_ptr e)
这是一个重载函数。
void QPromise::setProgressRange(int minimum, int maximum)
将计算的进度范围设置为在最小值和最大值之间。
如果最大值小于最小值,则仅以最小值为有效值。
进度值重置为最小值。
可以通过使用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()就会变为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)
将other移动分配到这个承诺,并返回对这个承诺的引用。
© 2024 Qt公司有限公司。此处包含的文档贡献是各自所有者的版权。本提供的文档受自由软件基金会发布的GNU自由文档许可证1.3版本的条款约束。Qt及相应的标志是芬兰以及全球其他地区的Qt公司商标。所有其他商标均为各自所有者的财产。