| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [Qt] Многопоточность |
| Автор: wowka19 12.6.2014, 02:01 |
| Есть возможность и острая нужда повысить быстродействие при помощи потоков. Программой будут пользоваться на различных машинах: 2 ядра, 4 а может и 8. Отсюда вопрос: нужно ли как-то обыгрывать этот неизвестный фактор? Т.е. нужно ли во время выполнения узнавать сколько ядер на машине и от этого плясать (кол-во потоков == кол-ву логических ядер)? или не стоит париться и жестко зашить 8 потоков (или 16 про запас)? Не будет ли проблем или просадок когда потоков будет 8, а ядер - 2? |
| Автор: borisbn 12.6.2014, 08:23 |
| > нужно ли во время выполнения узнавать сколько ядер на машине и от этого плясать (кол-во потоков == кол-ву логических ядер)? Нужно. Обязательно. Тем более, что это делается просто - http://qt-project.org/doc/qt-4.8/qthread.html#idealThreadCount |
| Автор: wowka19 12.6.2014, 14:50 |
| а почему? почему нельзя создать кучу потоков про запас? они же всеравно выполнятся. |
| Автор: borisbn 12.6.2014, 14:59 |
| Переключение между потоками на одном ядре гораздо более затратная вещь, чем переключение между ядрами. У меня как-то была программа, в которой крутилось 48 потоков (по количеству каналов обработки). "Кушала" она около 40 % процессора. Когда я перевёл её на 8 потоков (по кол-ву ядер) и в каждом последовательно (!!) обрабатывал по 6 каналов, она стала кушать около 30 %. Выигрыш в производительности - четверть. Там, правда, ещё была запись на винт (из всех потоков - в один каталог), и м.б. это тоже повлияло... хз. В общем, есть только одно средство проверить... и ты, я думаю, догадываешься какой |
| Автор: math64 12.6.2014, 17:50 |
| Есть такая штука - QtConcurent. Сама определит оптимальное количество потоков и создаст их. Ей нужно будет давать задания, а она сама распределит их по потокам. |
| Автор: wowka19 13.6.2014, 17:40 |
| Не могу понять QThread. В голове каша. Задача: фоном подгружать картинки в GUI с диска. Естественно нужен отдельный поток. Но как это сделать хз - никогда раньше не писал многопоточный код. Примеры из доки вроде понятны, но приступаю к своей задаче и впадаю в ступор. Буду признателен, если кто приведет кусок кода для подгрузки картинки (либо любого другого ресурса) фоном. Как потом производить передачу этого ресурса в основной поток, как сбросить работу фонового потока, если он уже не актуален и нужен другой ресурс... |
| Автор: math64 13.6.2014, 20:39 |
| Нужный тебе пример включен в Qt - если, конечно, ты согласен использовать QtConcurent вместо простого QThread. |
| Автор: wowka19 14.6.2014, 09:04 |
| нет. хочу разобраться с QThread, но нифига не получается. Немного конкретизирую задачу: Есть QGraphicsPixmapItem в главном потоке. Необходимо в другом потоке подгрузить создать QPixmap и как-то его всунуть в QGraphicsPixmapItem::setPixmap(const QPixmap&). При этом QPixmap, хранящийся в QGraphicsPixmapItem, очевидно считывается главным потоком, поэтому надо как-то заблокировать или не надо... Мне бы кусочек кода, реализующий это (не надо компилируемый). |
| Автор: borisbn 14.6.2014, 13:00 | ||||||
Тебе нужно в наследнике потока создать сигнал типа
В главном потоке после создания потока обработки сделать connect m_workThread = new WorkThread();
и дёргать сигнал в потоке обработки
|
| Автор: wowka19 16.6.2014, 18:46 |
| ... при этом (продолжая предыдущий пост borisbn) не забыть переместить объект потока в контекст этого же потока - я наконец-то разобрался с QThread. Спасибо всем кто помогал! Но я не наследую QThread, а создаю потомка QObject - загрузчика картинок и перемещаю его в контекст созданного потока QThread ( QObject::moveToThread(QThread*) ) - так имхо логичнее и понятнее ибо Qt'шные доки (где наследуется QThread и перегружается run()) только запутывают. Это я пишу для следующих вопрошающих (авось пригодится). Остался один вопрос: В итоге у меня два объекта из разных потоков общаются между собой через сигналы/слоты - здесь проблем никаких, но конечно же не обошлось без общих переменных, которые запрашиваются из обоих потоков. Их две и обе переменные имеют тип BOOL. Вопрос - надо ли их защищать от одновременного обращения? или запись и чтение BOOL - так скажем, "атомарные" операции, и не могут осуществляться одновременно даже если потоки выполняются на разных физических ядрах? Добавлю, что я их (переменные) не защищал, и у меня все работает без сбоев, хотя может мне просто повезло и при других условиях (компилятор, ОСь,..) все может рухнуть?.. |