Многопоточность в QT с использованием QtConcurrent

Я разрабатываю приложение на Qt, которое в какой-то момент обрабатывает кучу видео. Он работает нормально, но на этапе процесса у него было только 40-60% использования процессора, поэтому я попытался сделать его многопоточным.

Я использовал QtConcurrent, потому что его `` высокий уровень '' вместо более традиционного управления потоками, мой код просто:

for(int i = 0; i < totalVideos; i++)
{
    QFuture<ResultClass *> futureToken = QtConcurrent::run(this, process, listOfVideos.takeFirst());
    QFutureWatcher<ResultClass *>* fw = new QFutureWatcher<ResultClass *>();
    connect(fw, SIGNAL(finished()), this, SLOT(manageResult));
    fw->setFuture(futureToken);
}

ааа и он работает, 100% использование процессора и примерно на 25-30% быстрее. Но он порождает около 65 новых потоков (независимо от того, обрабатывает ли он 25 или 250 видео), и большинство из этих потоков не исчезают после фазы процесса.

Мой вопрос: правильный ли этот подход? Он слишком сырой? Должен ли я управлять созданием потока «вручную»? Обо всем позаботится модуль QtConcurrent, поэтому мне не нужно заботиться об управлении потоками? 85 потоков слишком много? Должен ли я попытаться убить некоторых из них после фазы процесса?

Все наблюдения производились только при просмотре монитора активности.

Заранее спасибо.


person Sommerwild    schedule 14.11.2013    source источник
comment
другой вариант - использовать QThreadPool и напрямую ограничить количество потоков (также утечки из futureWatcher, если вы не удалите его в слоте manageResult)   -  person ratchet freak    schedule 14.11.2013
comment
Да, я удаляю их (с помощью deleteLater ()) в слоте, спасибо, что указали на это.   -  person Sommerwild    schedule 14.11.2013
comment
технически они все еще протекают, когда this уничтожается до завершения будущего (добавьте это в конструктор, чтобы исправить это)   -  person ratchet freak    schedule 14.11.2013


Ответы (1)


Будущее QtConcurrent кажется неопределенным, если вы прочитаете эту ветку .

Наличие большего количества потоков, чем обрабатывающих ядер, в некоторой степени избыточно. Если у вас работает одно ядро ​​и 2 потока, процессор тратит время на переключение между обработкой 2 потоков, но дает пользователю видимость одновременной обработки.

При одинаковом количестве ядер и потоков потоки можно разделить между ядрами.

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

Использование QThread на самом деле очень просто, поскольку QThread не является непосредственно потоком, а является его контроллером. Вы можете прочитать о том, как 'действительно действительно используйте QThreads' здесь.

Как описано, вы создаете объекты, унаследованные от QObject, и перемещаете их в QThread. Что редко упоминается, так это то, что при необходимости вы можете переместить несколько объектов в новый QThread.

person TheDarkKnight    schedule 14.11.2013
comment
Я знаю, что это избыточно, но я их не создавал. Я думаю, что QtConcurrent перемещает задачу в соответствующие потоки, о которых говорится в документации: Выполняет функцию в отдельном потоке. Поток берется из глобального QThreadPool. Обратите внимание, что функция не может работать сразу; функция будет запущена только тогда, когда поток доступен. Я не знаю, откуда берутся все эти порождения потоков. - person Sommerwild; 14.11.2013
comment
Может случиться так, что все, что делает обработка видео, также порождает потоки. Я предлагаю преобразовать ваш код для использования QThread и посмотреть, какую производительность вы получите в качестве сравнения. - person TheDarkKnight; 14.11.2013
comment
Я сделаю это и опубликую результаты. - person Sommerwild; 14.11.2013
comment
Наличие большего количества потоков, чем ядра [sic] обработки, в некоторой степени избыточно - только если параллельные задачи предназначены только для вычислений; если задачи имеют какие-либо операции ввода-вывода, тогда может быть желательно больше потоков, чтобы предотвратить простоя ядер, когда они могут обрабатывать. - person boycy; 15.07.2014