Множественный порядок выполнения QtConcurrent :: map - PullRequest
0 голосов
/ 16 июня 2020

Допустим, у меня есть вектор из 100 элементов и Func1 и Func2. В однопоточной версии Func1 обрабатывают векторные элементы, и когда Func1 завершает работу, Func2 должен запускать другой процесс для элементов. Мне любопытно узнать, использую ли я QtConcurrent::map в следующем порядке, в каком порядке на самом деле будут выполняться Func1 и Func2?

QFuture<void> future;
future = QtConcurrent::map(vector, Func1);
future = QtConcurrent::map(vector, Func2);

Я должен упомянуть, что использование future.waitForFinished() заблокирует основной поток моего приложения которого я не хочу.

future = QtConcurrent::map(vector, Func1);
future.waitForFinished();
future = QtConcurrent::map(vector, Func2);

Также я не хочу выполнять эти QtConcurrent::map во вторичном потоке и выполнять future.waitForFinished() там, потому что при таком подходе я потеряю один из своих потоки в катушке ниток. Итак, вопрос в том, выполняются ли задачи, добавленные QtConcurrent::map, по порядку?

EDIT

Как в однопоточных, так и в многопоточных подходах Func2 должен запускаться только после Func1 заканчивает обработку всех элементов.

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Поскольку вы хотите, чтобы все вызовы на Func1 завершались до того, как будут сделаны какие-либо вызовы на Func2, вы не можете сделать второй вызов QtConcurrent::map до того, как станет известно, что первый завершился.

Однако вместо вызова future.waitForFinished() вы можете использовать QFutureWatcher ...

QFutureWatcher<void> watcher;
auto future = QtConcurrent::map(vector, Func1);
QObject::connect(&watcher, &QFutureWatcher::finished,
                 [&]()
                   {

                     /*
                      * All calls to Func1 have finished so it's
                      * safe to invoke Func2.
                      */
                     future = QtConcurrent::map(vector, Func2);
                   });
watcher.setFuture(future);

Вышеупомянутое не проверено, но, надеюсь, дает вам некоторое представление о том, что требуется.

0 голосов
/ 16 июня 2020

К сожалению, мне не удалось найти ответ в документации, поэтому я протестировал этот код

future = QtConcurrent::map(vector, Func1);
future = QtConcurrent::map(vector, Func2);

, и в результате для некоторых элементов вектора Func2 запускается раньше Func1. Также отсутствует последовательный порядок обработки элементов вектора, что естественно при использовании QtConcurrent::map.

Для решения моей проблемы я переместил объект со слотом, который вызывал оба QtConcurrent::map, в другой поток и использовал wait, что приведет к потере одного потока в моем пуле потоков.

...