Russian Qt Forum
Ноябрь 24, 2024, 14:00
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Общие вопросы
>
Остановка потока при уничтожении QThread
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Остановка потока при уничтожении QThread (Прочитано 13271 раз)
Осенний дождь
Гость
Остановка потока при уничтожении QThread
«
:
Май 23, 2007, 12:00 »
Доброе время суток.
Господа, у меня теоретический вопрос. Почему при уничтожении объекта QThread не завершается поток который он обслуживал?
Вот цитата из документации по Qt 4.2.2
Цитировать
Note that deleting a QThread object will not stop the execution of the thread it represents. Deleting a running QThread (i.e. isFinished() returns false) will probably result in a program crash. You can wait() on a thread to make sure that it has finished.
Кто-нибудь знает почему так сделано?
Записан
goer
Гость
Остановка потока при уничтожении QThread
«
Ответ #1 :
Май 23, 2007, 14:29 »
Дык, тут же и ответ:
Цитировать
Deleting a running QThread (i.e. isFinished() returns false) will probably result in a program crash. You can wait() on a thread to make sure that it has finished.
Записан
Осенний дождь
Гость
Остановка потока при уничтожении QThread
«
Ответ #2 :
Май 23, 2007, 18:57 »
Тут написано, что удаление запущенного потока опасно, но если программист все же решил удалить этот объект разумнее остановить поток!
В этом случае мы можем получить области данных в которых не был завершен процес модификации данных, заблокированные mutex и симофоры и т.д. Однако, если удалить объект не завершая поток, то рискуем получить еще худшую ошибку. Исполняемый код функции run() будет находиться в освобождаемой области данных и в результате программа выполнит недопустимую операцию или обратиться к недопустимому адресу.
Можете ли вы привести пример когда объект можно уничтожить не завершая поток (при условии что поток все еще выполняется)?
Записан
goer
Гость
Остановка потока при уничтожении QThread
«
Ответ #3 :
Май 23, 2007, 19:33 »
А зачем объект уничтожать не завершая поток? Уничтожать объект QThreda надо только после того как он закончит свою работу, для этого они и рекомендуют в общем случае ставить wait() в деструкторе. Правда это не обязательно.
Отследить момент когда поток должен быть остановлен нужно самому, затем остановить его и можно безболезненно удалять тем же delete(). Вот только не факт, что поток остановится сразу после вызова exit(). Для этого и рекомендуют ставить wait() в деструкторе.
Это просто рекомендация, как с умными указателеями: никто не говорит что это единственно правильный путь, но он гораздо легче остальных.
Записан
Осенний дождь
Гость
Остановка потока при уничтожении QThread
«
Ответ #4 :
Май 24, 2007, 10:27 »
Мы не вполне понимаем друг друга.
Попробую сказать по другому. Представте, что вы автор библиотеки Qt. И вот, вы приступили к написанию класса QThread. Добавили бы вы вызов terminate() в деструктор QThread? Я бы добавил. Класс уничтожается и значит поток с котором он был ассоциирован должен быть завершен. Это логично. Он авторы поступили по другому и мне интересно какие у них были причины.
Записан
goer
Гость
Остановка потока при уничтожении QThread
«
Ответ #5 :
Май 24, 2007, 10:52 »
Читаем еще раз.
НИ terminate(), НИ exit() НЕ гарантируют что поток будет немедленно остановлен. Дальше понятно?
Записан
Emc
Гость
Остановка потока при уничтожении QThread
«
Ответ #6 :
Май 24, 2007, 11:13 »
Цитата: "goer"
НИ terminate(), НИ exit() НЕ гарантируют что поток будет немедленно остановлен.
что вобщем то правильно - единственный разумный подход
создать флаг в Thread::run глобальный естественно - чтоб можно изменить извне - вот, далее там же (в теле run) ставим проверки
if (!flag) return; и на signal QThread::finished() вешаем слот с thread->delateLater();
гарантированно работает - позволяет прерывать thread в любой момент
Записан
goer
Гость
Остановка потока при уничтожении QThread
«
Ответ #7 :
Май 24, 2007, 11:35 »
Цитата: "Emc"
Цитата: "goer"
НИ terminate(), НИ exit() НЕ гарантируют что поток будет немедленно остановлен.
что вобщем то правильно - единственный разумный подход
создать флаг в Thread::run глобальный естественно - чтоб можно изменить извне - вот, далее там же (в теле run) ставим проверки
if (!flag) return; и на signal QThread::finished() вешаем слот с thread->delateLater();
гарантированно работает - позволяет прерывать thread в любой момент
А еще можно через wait() в деструкторе или через кучу других способов. Тут уж кто как считает разумнее.
Если "Осенний дождь" интересуют технические детали почему невозможно взять и остановить поток в любой момент, то он может поковырятся в сорцах... винды, юникса, мака.
Да и вобще, даже если не вникать в такие подробности - если поток например, принимает данные из сети, как ты предлагаешь его останавливать? В лоб удалять сокеты принимающие данные? Вряд ли юзеру понравится окошко с предложением отправить отчет МС-у.
Записан
Alex03
Гость
Остановка потока при уничтожении QThread
«
Ответ #8 :
Май 24, 2007, 11:36 »
Цитата: "Осенний дождь"
Попробую сказать по другому. Представте, что вы автор библиотеки Qt. И вот, вы приступили к написанию класса QThread. Добавили бы вы вызов terminate() в деструктор QThread? Я бы добавил. Класс уничтожается и значит поток с котором он был ассоциирован должен быть завершен. Это логично. Он авторы поступили по другому и мне интересно какие у них были причины.
Что делает поток - знаете только Вы. Тупо прибивать отдельный поток - имеет змысл очень редко (чаще вместе со всем приложением). Практически в любом маломальски значительном потоке будут как минимум динамическое выделение памяти, не говоря уж о всяких блокировках, работе с девайсами и т.д. И как следствие - утечки памяти (и прочий гемор) при убийстве потока.
Ну а если Вам действительно нужен terminate() в деструкторе - так всё ж в Ваших руках.
Но лучше всё-же контролировать какойнить объект синхронизации в потоке, и завершаться по соответствующему условию.
Записан
Emc
Гость
Остановка потока при уничтожении QThread
«
Ответ #9 :
Май 24, 2007, 12:48 »
Цитировать
А еще можно через wait() в деструкторе или через кучу других способов
wait ждет завершения работы потока --- мой способ прерывает его в любой момент
куча других способов -- очень интересно
примеры пожалуйста -- действительно интересно - мой подход с флагом имеет кучу недостатков - хотелось бы найти действительно хороший вариант
Записан
goer
Гость
Остановка потока при уничтожении QThread
«
Ответ #10 :
Май 24, 2007, 14:24 »
Общая стратегия, как правильно писал Alex03, это контролировать объект синхронизации в потоке. В данном случае просто флаг - слишком примитивный объект синхронизации. От задачи к задаче реализация будет менятся и искать единственно правильный вариант в программировании вообще, простите, глупо.
Записан
Emc
Гость
Остановка потока при уничтожении QThread
«
Ответ #11 :
Май 24, 2007, 15:40 »
угу только вот не всегда синхронизация нужна
ну я так понимаю кроме как ввода спец. проверки для принудительного выхода из QThread::run никто предложить не может --- одни рассуждения о множестве вариантов
пожалуйста приведите конкретный пример с qt кодом
у меня самого программа использует qthread и мне очень хотелось бы увидеть способы принудительного завершения
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...