QPromise 类

template <typename T> class QPromise

QPromise 类提供了一种将计算结果保存在 QFuture 中以供访问的方法。 更多...

头文件 #include <QPromise>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core
Qt 6.0

注意:此类中的所有函数都是 线程安全 的。

公共函数

QPromise()
QPromise(QPromise<T> &&other)
~QPromise()
booladdResult(const T &result, int index = -1)
booladdResult(T &&result, int index = -1)
(since 6.6) booladdResults(const QList<T> &results)
(since 6.6) boolemplaceResult(Args &&... args)
(since 6.6) boolemplaceResultAt(int index, Args &&... args)
voidfinish()
QFuture<T>future() const
boolisCanceled() const
voidsetException(const QException &e)
voidsetException(std::__exception_ptr::exception_ptr e)
voidsetProgressRange(int minimum, int maximum)
voidsetProgressValue(int progressValue)
voidsetProgressValueAndText(int progressValue, const QString &progressText)
voidstart()
voidsuspendIfRequested()
voidswap(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)

在内部结果集的位置 indexemplaceResultAt())或集合的末尾添加由 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::isFinishedQFuture::waitForFinishedstart

QFuture<T> QPromise::future() const

返回与此承诺关联的未来。

bool QPromise::isCanceled() const

返回计算是否已使用QFuture::cancel()函数取消。返回值true表示应该完成计算并调用finish()。

注意:在取消后,一个未来仍可以访问当前可用的结果,但在调用addResult()时不会添加任何新结果。

void QPromise::setException(const QException &e)

将异常e设置为计算的最终结果。

注意:在整个计算执行过程中,只能设置最多一个异常。

注意:此方法不得在QFuture::cancelfinish之后使用。

另请参阅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)

分别将计算的进度值和进度文本设置为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()就会变为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公司商标。所有其他商标均为各自所有者的财产。