Класс QPromise
шаблон <typename T> class 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 — это объект, используемый только для перемещения. Это поведение помогает гарантировать, что при уничтожении обещания связанный объект future уведомляется и не будет вечно ждать получения результатов. Однако это неудобно, если вы хотите использовать то же обещание для отчётности результатов из разных потоков. На данный момент нет специфического способа сделать это, но существуют известные механизмы, такие как использование умных указателей или сырых указателей/ссылок. 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
Возвращает значение true, показывая, была ли отменена задача с помощью функции QFuture::cancel(). Возвращаемое значение true указывает, что вычисление должно быть завершено и вызван finish().
Примечание: После отмены к результатам, которые в данный момент доступны, всё ещё можно получить доступ с помощью future, но новые результаты не будут добавлены при вызове 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.1/qpromise.html