QPromise Class
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(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 构建。
当需要细粒度控制时,您可以使用基于 QPromise 的工作负载来替代 Qt Concurrent当需要细粒度控制或与QFuture 配套的高级通信基元已经足够时,您可以使用基于 QPromise 的工作负载来替代 QPromise 框架。
最简单的承诺与未来协作案例就是单一结果通信:
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 是一个只允许移动的对象。这种行为有助于确保每当承诺被销毁时,关联的未来对象都会收到通知,而不会永远等待结果可用。但是,如果要使用同一承诺从不同线程报告结果,这就不方便了。目前还没有具体的方法来做到这一点,但已知的机制已经存在,例如使用智能指针或原始指针/引用。如果想复制承诺并同时在多个地方使用,QSharedPointer 是一个不错的默认选择。从某种意义上说,原始指针或引用更简单,性能也可能更好(因为不需要进行资源管理),但可能会导致悬空。
下面是一个如何在多个线程中使用 promise 的示例:
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();
另请参见 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() 上循环更有效率,因为每次调用 addResults() 时,相关期货才会收到一次通知,而不是像调用addResult() 时那样,results 中包含的每个元素都会收到一次通知。但是,如果每个元素的计算都需要时间,那么接收端(future)的代码在报告所有结果之前就无法取得进展,因此只有在连续元素的计算速度相对较快时才能使用该函数。
此函数在 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)
将计算的进度范围设置为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() 就会变成true
。
以下代码片段展示了暂停机制的用法:
// 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() 请求相关的承诺暂停:
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 赋值给此 promise,并返回此 promise 的引用。
© 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.