Qt Concurrent
Модуль Qt Concurrent предоставляет высокоуровневые API, которые позволяют писать многопоточные программы без использования низкоуровневых потоковых примитивов, таких как мьютексы, блокировки чтения-записи, условия ожидания или семафоры. Программы, написанные с использованием Qt Concurrent, автоматически настраивают количество используемых потоков в соответствии с количеством доступных процессорных ядер. Это означает, что приложения, написанные сегодня, будут продолжать масштабироваться при развертывании на многоядерных системах в будущем.
Qt Concurrent включает API функционального стиля для параллельной обработки списков, включая реализацию MapReduce и FilterReduce для систем с общей памятью (не распределённых), и классы для управления асинхронными вычислениями в приложениях с графическим интерфейсом:
-
Параллельное преобразование и MapReduce
- QtConcurrent::map() применяет функцию к каждому элементу в контейнере, изменяя элементы на месте.
- QtConcurrent::mapped() похож на map(), за исключением того, что он возвращает новый контейнер с изменениями.
- QtConcurrent::mappedReduced() похож на mapped(), за исключением того, что изменённые результаты сводятся или складываются в одно единственное значение.
-
Параллельное фильтрация и FilterReduce
- QtConcurrent::filter() удаляет все элементы из контейнера на основе результата функции фильтрации.
- QtConcurrent::filtered() похож на filter(), за исключением того, что он возвращает новый контейнер с отфильтрованными результатами.
- QtConcurrent::filteredReduced() похож на filtered(), за исключением того, что отфильтрованные результаты сводятся или складываются в одно единственное значение.
-
Параллельное выполнение
- QtConcurrent::run() выполняет функцию в другом потоке.
-
Параллельная задача
- QtConcurrent::task() создаёт экземпляр QtConcurrent::QTaskBuilder. Этот объект можно использовать для настройки параметров и запуска задачи в отдельном потоке.
- QFuture представляет результат асинхронного вычисления.
- QFutureIterator позволяет итерироваться по результатам, доступным через QFuture.
- QFutureWatcher позволяет отслеживать QFuture с помощью сигналов и слотов.
- QFutureSynchronizer — это удобный класс, который автоматически синхронизирует несколько QFutures.
- QPromise предоставляет способ сообщать о ходе выполнения и результатах асинхронного вычисления QFuture. Позволяет приостанавливать или отменять задачу по запросу QFuture.
Qt Concurrent поддерживает несколько типов контейнеров и итераторов, совместимых со STL, но лучше всего работает с контейнерами Qt, имеющими итераторы с произвольным доступом, такие как QList. Функции map и filter принимают как контейнеры, так и начальные и конечные итераторы.
Обзор поддержки итераторов STL:
| Тип итератора | Примеры классов | Статус поддержки |
|---|---|---|
| Итератор ввода | Не поддерживается | |
| Итератор вывода | Не поддерживается | |
| Итератор вперёд | std::slist | Поддерживается |
| Двунаправленный итератор | std::list | Поддерживается |
| Итератор с произвольным доступом | QList, std::vector | Поддерживается и рекомендуется |
Итераторы с произвольным доступом могут быть быстрее в случаях, когда Qt Concurrent итерируется по большому количеству лёгких элементов, так как они позволяют перейти к любой позиции в контейнере. Кроме того, использование итераторов с произвольным доступом позволяет Qt Concurrent предоставлять информацию о ходе выполнения через QFuture::progressValue() и QFutureWatcher::progressValueChanged().
Функции, не изменяющие значения на месте, такие как mapped() и filtered(), создают копию контейнера при вызове. Если вы используете контейнеры STL, эта операция копирования может занять некоторое время, в этом случае рекомендуется указать начальный и конечный итераторы для контейнера вместо него.
Использование модуля
Использование модуля Qt требует линковки с библиотекой модуля, либо напрямую, либо через другие зависимости. Несколько инструментов сборки предоставляют специализированную поддержку этого, включая CMake и qmake.
Сборка с помощью CMake
Используйте команду find_package() для поиска необходимых компонентов модуля в пакете Qt6.
find_package(Qt6 COMPONENTS Concurrent REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Concurrent)
См. также обзор Сборка с помощью CMake.
Сборка с помощью qmake
Для настройки модуля для сборки с помощью qmake добавьте модуль в качестве значения переменной QT в файле проекта .pro:
QT += concurrent
Эволюция модуля
Изменения в Qt Concurrent перечисляет важные изменения в API и функциональности модуля, которые были внесены для Qt 6 серии Qt.
Лицензии
Модуль Qt Concurrent доступен по коммерческим лицензиям от The Qt Company. Кроме того, он доступен по лицензиям свободного программного обеспечения: GNU Lesser General Public License, версия 3 или GNU General Public License, версия 2. Дополнительную информацию см. в Qt Licensing.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qtconcurrent-index.html