LINUX.ORG.RU

Qt, торможение основного цикла обработки сообщений.


0

1

Почему может тормозить обработка юзерских действий в Qt-окне во время создания вычислительной нагрузки в другом потоке (запущенном через boost::thread), при наличии 4 свободных ядер (core i5)?

Кутешный цикл обработки событий работает спокойно в своём треде. Общение кутешной морды с вычислительным тредом неблокируемое - т.е. когда морда (GUI1) делает вызовы в вычислительный модуль (M1), то максимум что происходит в этих вызовах - это «закинуть задачу в шедулер и пнуть семафор». Если бы морда блокировалась, т.е. фактически кутешный цикл обработки событий блокировался бы в вызове модуля M1, у меня морда бы зависала наглухо. А она не зависает, а начинает жёстко тормозить.


Подробнее...

У меня есть кутическая морда (GUI1), через несложный интерфейс связанная с другим модулем (M1), в котором через boost::thread запускается поток и выполняет задачу, настроенную в морде, по нажатию кнопки «start» из той же морды. По окончании задачи M1 докладывает об этом морде (GUI1) и морда может, например, разблокироваться или ещё чё-нибудь такое сделать.

M1 слабо связан с GUI1 вообще - делает в морду очень редкие вызовы, типа просьбы вывести текстовую строку.

Что это может быть, какие версии?

неблокируемое

пнуть семафор

морда может, например, разблокироваться или ещё чё-нибудь такое сделать

M1 слабо связан с GUI1 вообще

Не уверен, что в твоих словах нет противоречий.

mi_estas
()

Первое, что бы я рекомендовал сделать - приложение из одной кнопки и поток с циклом, в котором активно что-то считается. Иногда можно выводить результат на форму.
Проверить работу такой связки.
Если не заработает - исходники в студию, будем разбираться.
Если заработает - ошибка в вашем связывании формы и потока.

trex6 ★★★★★
()
Ответ на: комментарий от blinkenlichten

Понятно, что без исходников вы ничего не скажете, но мне точно не нужно. Может быть есть что-то такое, что есть на памяти у бывалых Qt-девелоперов, что-то такое, на что они могут посоветовать обратить внимание просто.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Как и куда соединяешь кнопочку «старт»? Какой механизм используешь для уведомления М1 -> GUI1 после окончания работы?

mi_estas
()
Ответ на: комментарий от kiverattes

> Ну я ж пишу, что нет блокирования, есть торможение.

Торможение может быть частным случаем частого блокирования/разблокирования. Вполне реален случай, когда в главном потоке стоит цикл, проверяющий что-то до бесконечности, а отдельный поток постоянно обновляет это «что-то», заставляя тот цикл подтормаживать. Ещё вполне возможно, что тормозят иксы.

Попробуйте проверить на количестве потоков N-1.

У меня есть программа на Qt, кодирующая музыку в несколько потоков, на 100% нагружая все ядра. Все потоки постоянно общаются с главным циклом, докладывая о прогрессе, а GUI в реальном времени обновляет статистику. Всё работает плавно без заиканий: http://gitorious.org/fogg

Dendy ★★★★★
()
Ответ на: комментарий от mi_estas

1. Кнопочка вызывает M1::cmdRun(), в котором делается только только boost::condition_variable::notify_one(); 2. M1 -> GUI1 об окончании работы не уведомляется, а уведомляется о факте начала или конца работы какого-либо треда без указания какого-либо ID-треда. То есть если работу начали 5 потоков, счётчик накрутился до 5. Когда они останавливаются, они говорят «я кончел» и когда счётчик достигает 0, гуй разблокируется. Проверок в циклах нет, просто стоит реакция на переход счётчика из состояния «>0» в состояние «==0».

kiverattes ★☆
() автор топика
Ответ на: комментарий от Dendy

Да нет у меня такого, работает только один тред. На самом деле там тредов 20 запускается, просто M1 очень сложный внутри и разработан >1 человеком, но с гуём он связан очень слабо. При этом из всего зоопарка тредов, проц жрёт только 1.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Грёбаное LOR-форматирование, вечно всё не как у людей.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Я бы на вашем месте замерил где именно тормозит. Между итерациями основного цикла или внутри вашей собственной логики. И постепенно сужать круг подозреваемых, чтобы докопаться до сути проблемы.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Трудно пока догадаться, чё делать. Это вообще не критично и я скорее всего забью... Но GUI отлично быстро выводит сообщения от M1, без проблем обновляет прогресс-бар, но действия от юзера, типа перемещения или ресайза - с тормозами. Если бы GUI застрял в каком-то вызове M1, тогда он вообще бы не работал, не перерисовывался, не ресайзился и т.п. А он и ресайзится и кнопочки в нём нажимаются и т.п., но, собака, с тормозами. При этом вызовов в M1 никаких точно не идёт, у меня там их вообще пара штук - один cmdRun(), второй типа «зафигарить набор параметров» (вызывается перед cmdRun()).

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

гуй разблокируется

Вопрос по терминологии. Что значит «разблокируется»? В смысле кнопочки становятся активными (или другие графические элементы там) или это значит, что он сидел на семафоре и вдруг пошёл дальше?

они говорят «я кончел»

you made my day, bro.

Как вариант, возми профайлер и посмотри. Хотя в общем-то если по уму, то это надо было стразу сделать.

mi_estas
()
Ответ на: комментарий от mi_estas

Да, кнопочки переводятся в enabled из disabled. Некоторые. Критические кнопочки, нажатие которых нежелательно во время беременности.

Профайлер - это для замера бутылочных горл, а тут нужно что-то другоё.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Он тебе покажет в каком месте у тебя отъедается больше всего времени. Может и не помочь, согласен, но для общей картины не повредит.

mi_estas
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.