Класс QPromise
шаблон <typename T> класс QPromiseКласс QPromise предоставляет способ хранения результатов вычислений, к которым можно получить доступ с помощью QFuture. Подробнее...
| Заголовок: | #include <QPromise> |
| CMake: | find_package(Qt6 COMPONENTS Core REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
| С версии: | Qt 6.0 |
Примечание: Все функции в этом классе являются безопасными для потоков.
Открытые функции
| QPromise(QPromise<T> &&other) | |
| QPromise() | |
| QPromise<T> & | operator=(QPromise<T> &&other) |
| ~QPromise() | |
| bool | addResult(const T &result, int index = -1) |
| bool | addResult(T &&result, int index = -1) |
| void | finish() |
| QFuture<T> | future() const |
| bool | isCanceled() const |
| void | setException(const QException &e) |
| void | setException(std::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 предоставляет простой способ передачи прогресса и результатов пользовательского вычисления в QFuture асинхронным способом. Для работы связи QFuture должен быть построен с помощью QPromise.
Вы можете использовать рабочие нагрузки на основе QPromise в качестве альтернативы фреймворку Qt Concurrent, когда требуется точный контроль или достаточна высокоуровневая коммуникационная примитива для сопровождения QFuture.
Самым простым случаем сотрудничества обещания и будущего будет одно сообщение об результате:
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 — это объект, который можно использовать только один раз. Это поведение помогает гарантировать, что при уничтожении обещания связанный объект будущего будет уведомлен и не будет ждать вечно результатов. Однако это неудобно, если вы хотите использовать одно и то же обещание для отчёта результатов из разных потоков. В настоящее время нет конкретного способа сделать это, но существуют известные механизмы, такие как использование умных указателей или сырых указателей/ссылок. QSharedPointer является хорошим выбором по умолчанию, если вы хотите скопировать своё обещание и использовать его в нескольких местах одновременно. Сырые указатели или ссылки, в некотором смысле, проще и, вероятно, работают быстрее (поскольку нет необходимости в управлении ресурсами), но могут привести к висящим ссылкам.
Вот пример того, как обещание можно использовать в нескольких потоках:
QSharedPointer<QPromise<int>> sharedPromise(new QPromise<int>());
QFuture<int> future = sharedPromise->future();
// ...
// 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 См. также QFuture.
Документация по членам функций
bool QPromise::addResult(T &&result, int index = -1)
bool QPromise::addResult(const T &result, int index = -1)
Добавляет result в внутренний набор результатов в позиции index. Если индекс не указан, result добавляется в конец набора.
Возвращает true при добавлении result в набор.
Возвращает false когда это обещание отменено или завершено, или когда result отклонено. addResult() отклоняет result, если в наборе уже есть другой результат, сохраненный в том же индексе.
Вы можете получить результат в определенном индексе, вызвав QFuture::resultAt().
Примечание: Можно указать произвольный индекс и запросить результат в этом индексе. Однако некоторые методы QFuture работают с непрерывными результатами. Например, итерационные подходы, которые используют QFuture::resultCount() или QFuture::const_iterator. Чтобы получить все доступные результаты, не задумываясь о пробелах в индексах или нет, используйте QFuture::results().
QPromise::QPromise(QPromise<T> &&other)
Перемещающее создание нового QPromise из other.
См. также operator=().
QPromise::QPromise()
Создаёт QPromise в состоянии по умолчанию.
QPromise<T> &QPromise::operator=(QPromise<T> &&other)
Перемещающее присваивание other этому обещанию и возвращает ссылку на это обещание.
QPromise::~QPromise()
Уничтожает обещание.
Примечание: Обещание неявно переходит в состояние отмены при уничтожении, если пользователь не вызовет finish() предварительно.
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 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
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().
void QPromise::swap(QPromise<T> &other)
Меняет местами обещание other с этим обещанием. Эта операция очень быстрая и никогда не терпит неудач.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.0/qpromise.html