| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > QThread поток не завершается |
| Автор: loneybibi 24.1.2012, 12:23 | ||||||
| Добрый день! Первый раз пробую что такое потоки. Так что сильно не ругать! Собственно вот класс потока:
В главном потоке с GUI перед его удалением выполняю выход из потока:
Но почему то все равно пишет ошибку и выход из потока не происходит:
Да и собственно само приложение теперь завершается очень долго после QMainWindow::close() проходит около 4 секунд. Объясните где тут ошибка и что тут не так пожалуйста! Прикрепил проект на всякий случай! |
| Автор: borisbn 24.1.2012, 12:36 |
| Может дело и не в этом, но классы, наследуемые от QObject (а твой mThread такой, т.к. наследуется от QThread, который наследуется от QObject), так вот, такие классы должны быть описаны в отдельном h-нике. Это нужно для moc-компилятора. Короче, попробуй вынести объявление mThread в отдельный h-ник и включи его в mainwindow.h |
| Автор: loneybibi 24.1.2012, 12:41 | ||
Попробовал все тоже самое. |
| Автор: kuzulis 24.1.2012, 13:00 | ||||
А если в run() оставить только:
то что? Скорее всего это изза:
Зачем использовать указатель на объект, созданный в другой нити из главной нити? Если уж создал QSqlDatabase, QSqlTableModel в mThread то они там и должны оставаться, не нужно выносить "мусор из избы" (с) А хотя, може быть, из-за того, что некому делать db.close()... Ты повыкидывай (позакомментируй) в run() разные строчки и узнаешь из-за чего. |
| Автор: loneybibi 24.1.2012, 14:11 | ||||||
В справке по Qt функция run() переопределялась как public:
Открыл вторую редакцию книги Макса Шлее по Qt. Увидел что там в примере, функция run() переопределяется как protected:
Вообщем перенес свою функцию в protected и все работает как часы:
Всем спасибо! |
| Автор: Sahab 24.1.2012, 18:33 |
| без разницы протектед или паблик. видимо изменил что-то ненароком) Добавлено через 2 минуты и 59 секунд мало того, на куте-лабсе был пост о том, что не нужно так делать. правильно - создавать объект db (инкапсулирующий работу с БД) и moveToThread ( QThread * targetThread ) в необходимый поток. |
| Автор: borisbn 24.1.2012, 18:39 | ||
в исполняемом коде эти надписи
абсолютно одинаковы. Проверь - измени сейчас в рабочем коде обратно protected на public и всё будет работать |
| Автор: loneybibi 24.1.2012, 22:13 | ||||
Я конечно не совсем уверен но они точно имеют различия. По логике зачем бы тогда был раздел ptotected и public. И извините меня конечно то тот проект что я выложил в первом посте и в конечно что я описал ничем не отличается кроме того что я перенес функцию run() в раздел protected!! Если мне не верите просто возьмите код из первого моего проекта и перенесите функцию run() в раздел protected! Просто проверьте! Я благодарен за ответы и я только начал изучать нити но это действительно так! Добавлено @ 22:19 Смыла врать мне нет. borisbn возьмите мой код и он будет работать с ошибкой. А если изменить на протектед то все ок ! Просто попробуйте! Win xp sp3 qt 4.7.4 |
| Автор: loneybibi 24.1.2012, 23:43 | ||
поясните примером пожалуйста как инкапсулировать и как переместить поток ! ? про инкапсуляции в поток и тд я еще не в курсе т.к. только начал изучать нити как и сказал выше ! Буду благодарен за примеры ! |
| Автор: loneybibi 25.1.2012, 00:00 |
| извините. Фух че то я запутался! очистил проект. перенес обратно в паблик функцию run(). собрал, все работает! но код тот же ! почему не работало до этого не понял вообще не понял! не менял ничего честно ! объясните пожалуйста тогда в чем разница между public и protected если для компилятора это один и тот же код ? только в зоне видимости объектов? |
| Автор: borisbn 25.1.2012, 09:38 | ||
Разница только в том, выдавать ли ошибку при компиляции, если кто-то пытается вызвать protected-функцию снаружи (или при private-наследовании... брррр...). В исполняемом же коде (ессно, если скомпилировалось без ошибок) разницы нет вообще никакой |
| Автор: daemonaz 10.2.2012, 11:22 |
| Скажите пожалуйста как получить результат завершения потока? Я в потоке в случае заверщения вызываю функцию exit(int), аргумент есть код возврата, мне нужно от потока получить этот код. |
| Автор: loneybibi 10.2.2012, 13:41 | ||
В переопределении функции run() есть exec() который запускает очередь сообщений потока вот она и возвращает код возврата, как в main.cpp функции main() в принципе. |
| Автор: daemonaz 10.2.2012, 14:53 |
| loneybibi, я не понял, зачем exec возврашать? Это же eventloop, или я чего то недопонимаю.. Запускаю поток, в котором нет бесконечного цикла, и exec я не использую, но в случае ошибки поток прерывает работу с помошью метода exit(int), нужно как только поток завершил работу, приложение, которое его запустило, должно проанализировать ошибку и выдать сообщение юзеру что произошла авария в работе потока. |
| Автор: loneybibi 11.2.2012, 01:56 | ||||
Я бы добавил в класс потока макрос Q_OBJECT и сделал сигнал по завершению выполнения функций потока. Например так:
|