Выполнение в нескольких потоках
Функция QtConcurrent::run() выполняет функцию в отдельном потоке. Возвращаемое значение функции доступно через API QFuture.
Данная функция является частью фреймворка Qt Concurrent.
Выполнение функции в отдельном потоке
Для выполнения функции в другом потоке используйте QtConcurrent::run():
extern void aFunction(); QFuture<void> future = QtConcurrent::run(aFunction);
Это запустит aFunction в отдельном потоке, полученном из стандартного QThreadPool. Вы можете использовать классы QFuture и QFutureWatcher для мониторинга состояния функции.
Для использования выделенного пула потоков вы можете передать QThreadPool в качестве первого аргумента:
extern void aFunction(); QThreadPool pool; QFuture<void> future = QtConcurrent::run(&pool, aFunction);
Передача аргументов функции
Передача аргументов функции осуществляется путем добавления их в вызов QtConcurrent::run() сразу после имени функции. Например:
extern void aFunctionWithArguments(int arg1, double arg2, const QString &string); int integer = ...; double floatingPoint = ...; QString string = ...; QFuture<void> future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string);
Копия каждого аргумента создается в момент вызова QtConcurrent::run(), и эти значения передаются потоку при его запуске. Изменения, внесенные в аргументы после вызова QtConcurrent::run(), не видны потоку.
Возвращение значений из функции
Любое возвращаемое значение из функции доступно через QFuture:
extern QString functionReturningAString(); QFuture<QString> future = QtConcurrent::run(functionReturningAString); ... QString result = future.result();
Как описано выше, передача аргументов выполняется следующим образом:
extern QString someFunction(const QByteArray &input); QByteArray bytearray = ...; QFuture<QString> future = QtConcurrent::run(someFunction, bytearray); ... QString result = future.result();
Обратите внимание, что функция QFuture::result() блокирует выполнение и ожидает получения результата. Используйте QFutureWatcher, чтобы получить уведомление о завершении выполнения функции и доступности результата.
Дополнительные возможности API
Использование методов-членов
QtConcurrent::run() также принимает указатели на методы-члены. Первый аргумент должен быть либо константной ссылкой, либо указателем на экземпляр класса. Передача по константной ссылке полезна при вызове константных методов-членов; передача по указателю полезна для вызова неконстантных методов-членов, которые изменяют экземпляр.
Например, вызов QByteArray::split() (константный метод-член) в отдельном потоке выполняется так:
// call 'QList<QByteArray> QByteArray::split(char sep) const' in a separate thread QByteArray bytearray = "hello world"; QFuture<QList<QByteArray> > future = QtConcurrent::run(bytearray, &QByteArray::split, ','); ... QList<QByteArray> result = future.result();
Вызов неконстантного метода-члена выполняется так:
// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread QImage image = ...; QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba); ... future.waitForFinished(); // At this point, the pixels in 'image' have been inverted
Использование связанных аргументов функции
Вы можете использовать std::bind() для связывания ряда аргументов с функцией при ее вызове. Если поддержка C++11 недоступна, boost::bind() или std::tr1::bind() являются подходящими альтернативами.
Существует ряд причин для связывания:
- Для вызова функции, принимающей более 5 аргументов.
- Для упрощения вызова функции с постоянными аргументами.
- Изменения порядка аргументов.
Подробности о том, как использовать API связывания, см. в документации по соответствующим функциям.
Вызов связанной функции выполняется следующим образом:
void someFunction(int arg1, double arg2); QFuture<void> future = QtConcurrent::run(std::bind(someFunction, 1, 2.0)); ...
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.6/qtconcurrentrun.html