Название: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 14:52 Есть такое дело, гуишный поток запускает дочерний, в методе run которого запущен while(true)... Умрут ли в таком случае сигналы и слоты в воркере? Нужно ли принудительно в том цикле обрабатывать евенты?
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Пантер от Август 24, 2012, 14:54 Кто такой воркер?
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Serr500 от Август 24, 2012, 15:05 Умрут ли в таком случае сигналы и слоты в воркере? Нужно ли принудительно в том цикле обрабатывать евенты? Да. Да.Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Igors от Август 24, 2012, 15:07 Ну не умрут но к ним нельзя будет достучаться т.к. EventLoop не крутится - то ли Вы его вообще не запустили (нет exec) то ли перебили while (true)
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 15:35 Пантер, воркер это Qthread с бесконечным лупом в run.
EventLoop не крутится - то ли Вы его вообще не запустили (нет exec) Именно, в run нет exec. Если будет exec то тогда не будет моего while(true), который так же необходим, как и EventLoop... А если в ране сделать что то типа Код то слоты начнут работать? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 15:41 Помойму кто-то чегой то не понимает. Вроде бы при запуске потока c переопределённым run, EventLoop создаётся. Слоты работать должны.
PS или у меня опять провалы в памяти и пара моих проектов работают чудом? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 15:46 Верес, неа, вот обычный run() из QThread
Код А вот и exec() Код Тут четко видно, что QEventLoop создается в exec(), так что, как подсказывает логика, свой QEventLoop тоже должен проканать... Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Serr500 от Август 24, 2012, 15:49 Помойму кто-то чегой то не понимает. Вроде бы при запуске потока c переопределённым run, EventLoop создаётся. Слоты работать должны. start() запускает run(), а Event Loop создаётся в exec(). Если до него в run() цикл, то Event Loop'а нет и, соответственно, сигналы не обрабатываются.А если в ране сделать что то типа Да.Код то слоты начнут работать? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Igors от Август 24, 2012, 15:54 Именно, в run нет exec. Если будет exec то тогда не будет моего while(true), который так же необходим, как и EventLoop... А если в ране сделать что то типа Не так, просто QAplication::processEvents, он static. Обычно нет смысла смешивать 2 техники (сигналы и свой while) Код то слоты начнут работать? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 16:02 Не так, просто QAplication::processEvents, он static. Обычно нет смысла смешивать 2 техники (сигналы и свой while) Дело в том, что в том цикле выполняются операции с сокетами в программе, которая совсем не написана на Qt, и мне просто нужно прикрутить к ней GUI. Если я буду запускать QAplication::processEvents() в том цикле, то всякие разные отрисовки, перерисовки, движения мышки могут достаточно ощутимо затормозить работу с сокетами, собственно, сигналы\слоты нужны только для нескольких функций(запустить обработку, остановить, узнать состояние). Потому то мне кажется, что мой вариант будет обрабатывать только то мизерное количество евентов, которое будет припадать на мой воркер, а не все евенты приложения. Если не прав, то поправляйте:).Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 16:47 Вот ненадо мне тут трындить. (это я к тем, которые трындят, что слоты умрут)
Код: void run() Сигнал слоты работают. Так что всё у ТСса работать будет со слотами. PS помоему такая холиварная тема уже поднималась. И там докопались вроде(давно было ), что start() вызывает exec, если переопределён run(). Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 16:51 Пантер, воркер это Qthread с бесконечным лупом в run. работать-то начнут, но так же и сожрется проц.EventLoop не крутится - то ли Вы его вообще не запустили (нет exec) Именно, в run нет exec. Если будет exec то тогда не будет моего while(true), который так же необходим, как и EventLoop... А если в ране сделать что то типа Код то слоты начнут работать? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 17:17 Код: void run() Сигнал слоты работают. Так что всё у ТСса работать будет со слотами. Чего холиварного в этой теме? Вот ненадо мне тут трындить. (это я к тем, которые трындят, что слоты умрут) А вот и докатились:... Сигнал слоты работают. Так что всё у ТСса работать будет со слотами. Bepec Джедай : наставник для всех ;D ;D ;D Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 17:31 Код: class SBFiber : public QThread andrew.k сам попробуй. Работают и внешние и внутренние слоты, НЕЗАВИСИМО откуда посылаются/принимаются сигналы. Я бы себе взял другой титул, но система для всех одна. PS я в отличие от тебя пробую/получаю результат/отвечаю ;) А не бросаюсь словами. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 17:33 PS я в отличие от тебя пробую/получаю результат/отвечаю ;) А не бросаюсь словами. не смеши меня!Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 17:34 Твоя реплика только доказывает мою правоту ;D
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 17:44 PS я в отличие от тебя пробую/получаю результат/отвечаю ;) А не бросаюсь словами. Тут и пробовать ничего. Эта "холиварная" тема не стоит и выеденного яйца.В отличие от тебя я понимаю, что пишу. В твоем примере слот к сигналу коннектится в режиме AutoConnection. А т.к. сигнал и слот в одном потоке, то они связываются через DirectConnection. Таким образов emit sig() в твоем примере просто прямой вызов слота (если тебе это о чем-то говорит). Для танкиста: этот сигнал не проходит через очередь. Для совсем танкиста можешь заменить emit sig(); на slot(); ничего не изменится! А вот если сигнал будет отправлен из другого потока, например, из ГУИ, то он никогда в жизни не дойдет до твоего слота в такой реализации! Либо добавь пятый параметр Qt::QueuedConnection. И сиди осознавай. Конечно же очевидно, что ты все это понимаешь, и именно это и имел ввиду, а я просто погорячился. >:( А по правде, ты очень достал своими бессмысленными и беспощадными изречениями. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 17:50 Твоя реплика только доказывает мою правоту ;D Мне в очередной раз стыдно за тебя, Джедай Верес.Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 17:51 Кхм. andrew.k включи логику. Зачем я приводил по твоему в первый раз кусок кода без сигнала? Затем, что сигнал, который вызывает приведённый слот подключен к кнопке на главной форме. И при нажатии кнопки (О чудо) происходит вызов слота :D
Да, согласен, чуть неясно получилось - слот недокопировал. PS ПОПРОБУЙ а потом говори, благодетель самаритянский :D Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Igors от Август 24, 2012, 17:58 Если я буду запускать QAplication::processEvents() в том цикле, то всякие разные отрисовки, перерисовки, движения мышки могут достаточно ощутимо затормозить Он возьмет EventLoop той нитки из которой вызван, соответственно только посланные ей события (сигналы) будут извлекаться. Надо только сделать exec(). Ваш вариант вполне возможен, просто ничего не выигрывает по сравнению с обычнымНазвание: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:06 Если я буду запускать QAplication::processEvents() в том цикле, то всякие разные отрисовки, перерисовки, движения мышки могут достаточно ощутимо затормозить Он возьмет EventLoop той нитки из которой вызван, соответственно только посланные ей события (сигналы) будут извлекаться. Надо только сделать exec(). Ваш вариант вполне возможен, просто ничего не выигрывает по сравнению с обычнымНазвание: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 18:11 Извиняюсь, был неправ :D
Всего то забыл moveToThread сделать :D По теме: а что мешает запустить еxec, и потом зациклить вызов функции whileBlaBlaBla() с помощью допустим таймера? Вроде же получится обычный цикл в потоке и поток будет принимать внешние сигналы, ннэ? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 18:15 Возможно, я не до конца описал проблему, все слоты должны запускаться в потоке-воркере. Теперь, несколько замечаний к Верес:
И там докопались вроде(давно было ), что start() вызывает exec, если переопределён run(). Какими же средствами с++ можно узнать, переопределялся ли метод?(конечно, можно сделать типа bool isRedefined = true,и стандартной реализации выставить в фолс, но Qt писался грамотными людьми, и такого быдлокода там нету:))Код: void run() Код слоты работают. Если надо, могу скинуть пример, который полностью обрисовывает ситуацию. там правда немного быдлокода, связано с тем, что потоки не успевают запуститься к тому моменту как я пробую емитить сигнал Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 18:17 Извиняюсь, был неправ :D Пока писал ответ, и проверал на примере, Вы сами муванули его :)Всего то забыл moveToThread сделать :D Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:18 Извиняюсь, был неправ :D Не в этом дело, а в том, что ты свой пример даже не запускал.Всего то забыл moveToThread сделать :D По теме: а что мешает запустить еxec, и потом зациклить вызов функции whileBlaBlaBla() с помощью допустим таймера? Редкий случай, когда Верес говорит, что-то дельное, поэтому переведу на человечий.Вроде же получится обычный цикл в потоке и поток будет принимать внешние сигналы, ннэ? Нужно то, что ты делаешь внутри своего while(true) разбить на подзадачи и выполнять каждый шаг по сигналу. Получил сигнал (от таймера или от того, кто тебе данные на обработку дает - обработал, дальше ждешь, получил - обработал). Но это если эти сигналы действительно нужны. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 18:21 Мой пример потому и запускался, что работал в 1 потоке ;)
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 18:30 Редкий случай, когда Верес говорит, что-то дельное, поэтому переведу на человечий. Та там столько действий в том цикле, что мне страшно даже трогать, не хочу поломать (программа не моя). А на то что processEvents() будет жрать процессорное время ээээ... Хотел заикнутся что не будет, потому что в exec() QEventLoop'а тоже в цикле вызывается processEvents(), но увидел в исходниках, что processEvents() в QEventLoop'е при отсутствии евентов их ожидает... А вариант с таймером почти подходит, но там сокеты... Хотелось бы моментального отклика, а не по таймеру...Нужно то, что ты делаешь внутри своего while(true) разбить на подзадачи и выполнять каждый шаг по сигналу. Получил сигнал (от таймера или от того, кто тебе данные на обработку дает - обработал, дальше ждешь, получил - обработал). Но это если эти сигналы действительно нужны. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: Bepec от Август 24, 2012, 18:33 Эмм... Таймер ставишь в 0 - получаешь такой же while(true) с работающими слотами :)
Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:37 Мой пример потому и запускался, что работал в 1 потоке ;) Ты свой пример даже не запуска ни разу, скопировал у какого-то дурака и размножаешь.Во вложении пример, который я написал. Вот и расскажи мне как же так в твоем примере сигналы успешно работают, а в моем нет? Что я делаю не так? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:40 Редкий случай, когда Верес говорит, что-то дельное, поэтому переведу на человечий. Та там столько действий в том цикле, что мне страшно даже трогать, не хочу поломать (программа не моя). А на то что processEvents() будет жрать процессорное время ээээ... Хотел заикнутся что не будет, потому что в exec() QEventLoop'а тоже в цикле вызывается processEvents(), но увидел в исходниках, что processEvents() в QEventLoop'е при отсутствии евентов их ожидает... Нужно то, что ты делаешь внутри своего while(true) разбить на подзадачи и выполнять каждый шаг по сигналу. Получил сигнал (от таймера или от того, кто тебе данные на обработку дает - обработал, дальше ждешь, получил - обработал). Но это если эти сигналы действительно нужны. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 18:44 Хм, посмотрел исходники той проги, там цикл вот такой:
Код 50000 - таймаут для функции http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx). + до того таймаута там выполняется еще куча всяких непонятных радостей... Теперь вопрос: можно ли сделать таймер так, что бы он не посылал новый сигнал до того, как завершится старый, и при этом что бы не блокировался GUI поток(мне бы стоило почитать доки про таймер, но как то жутко лень, и так сегодня начитался и доков, и сорцов...)? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:45 А вариант с таймером почти подходит, но там сокеты... Хотелось бы моментального отклика, а не по таймеру... Я думаю, что лучше тебе сделать так.Пишешь некоторый класс (ProblemSolver), вообще не думая о потоках, который делает всю эту работу, которая у тебя запихана в твой цикл. Это будет проще и кошернее. Затем создаешь два объекта QThread (оригинальный без всякого наследования) и свой класс ProblemSolver. и делаешь ему moveToThread. Код как-то так. И будет оно работать как надо. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 18:48 Хм, посмотрел исходники той проги, там цикл вот такой: Ты можешь просто игнорировать сигнал от таймера, если он тебе не нужен.Код 50000 - таймаут для функции http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx). + до того таймаута там выполняется еще куча всяких непонятных радостей... Теперь вопрос: можно ли сделать таймер так, что бы он не посылал новый сигнал до того, как завершится старый, и при этом что бы не блокировался GUI поток(мне бы стоило почитать доки про таймер, но как то жутко лень, и так сегодня начитался и доков, и сорцов...)? Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 19:06 А вариант с таймером почти подходит, но там сокеты... Хотелось бы моментального отклика, а не по таймеру... Я думаю, что лучше тебе сделать так.Пишешь некоторый класс (ProblemSolver), вообще не думая о потоках, который делает всю эту работу, которая у тебя запихана в твой цикл. Это будет проще и кошернее. Затем создаешь два объекта QThread (оригинальный без всякого наследования) и свой класс ProblemSolver. и делаешь ему moveToThread. Код как-то так. И будет оно работать как надо. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: andrew.k от Август 24, 2012, 19:08 А вариант с таймером почти подходит, но там сокеты... Хотелось бы моментального отклика, а не по таймеру... Я думаю, что лучше тебе сделать так.Пишешь некоторый класс (ProblemSolver), вообще не думая о потоках, который делает всю эту работу, которая у тебя запихана в твой цикл. Это будет проще и кошернее. Затем создаешь два объекта QThread (оригинальный без всякого наследования) и свой класс ProblemSolver. и делаешь ему moveToThread. Код как-то так. И будет оно работать как надо. Он просто будет кушать процессор и твоя забота, чтобы он его кушал не в холостую) По завершению из цикла нужно выйти и можно остановить поток, а можно и не останавливать. Название: Re: GUI поток и воркер, в котором запущен while(true)-умрут ли слоты? Отправлено: crashtua от Август 24, 2012, 20:26 Принял решение остановится на следующем варианте: класс Worker имеет слот, в котором содержится тело цикла while(true), в этом же классе(Worker) создается таймер с интервалом 50 мс. Создается поток, в него мувается мой Worker. Работает, тело цикла запускается с нужной периодичностью, слоты запускаются с созданого потока, GUI и Worker не оказывают негативного влияния один на другого. Всем спасибо за внимание, очень помогли.
|