Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Вопрос по QThread.


Автор: OlegIT 3.3.2015, 15:32
Есть поток, который нужно остановить. Это можно сделать функциями exit(), terminate(). В случае с exit() проверка isFinished() всегда даёт false, в случае terminate() выход функции isFinished() true. И, похоже, что exit() поток вообще не останавливает, так как при закрытии программы в окне <Вывод приложения> выводится «QThread: Destroyed while thread is still running». Может ошибаюсь.
Функция terminate() реализована в файлах qthread_win.cpp и qthread_unix.cpp. Для Android функция явно закрыта, вся её реализация под #if !defined(Q_OS_ANDROID). А что тогда делать с Android-ом?

Автор: vinter 7.3.2015, 07:56
Поток нужно останавливать из самого себя, т.е. держать какую-то разделяемую, атомарную переменную, которую выставлять в true. Это проверять в потоке и завершать основной цикл потока. Любое внешнее закрытие это в 99.99% случаев резальтат плохого решения или непонимания. 

Автор: OlegIT 7.3.2015, 22:44
Хорошо, "Любое внешнее закрытие это в 99.99% случаев резальтат плохого решения или непонимания." правильное мнение. Тогда зачем нужны функции exit(), terminate()?

Автор: vinter 8.3.2015, 12:13
Потому что требования бывают разные и нормальные разработчики языка/API не имеют права ограничивать программиста. В идеале, программиста должна ограничивать только голова, а не возможности API. Возможно, у кого-то есть ситуация при которой без terminate()/exit() не обойтись, просто я таковой придумать, с ходу, не могу.

Автор: OlegIT 10.3.2015, 08:52
А если у меня именно такой случай?
Вообще-то вопросы задал конкретные, почему exit() не убивает поток и как быть с Android версией функции terminate()? Если решения с terminate()/exit() нет, то тогда придётся возится с флажками и не одним, в моём случае.

Автор: bsa 11.3.2015, 16:07
OlegIT, exit() работает только тогда, когда у тебя в потоке запущен QEventLoop. Если он не запущен, то она ничего не делает.

terminate() работает только тогда, когда это разрешено (см. setTerminationEnabled).

Как уже сказал vinter, правильно это делать путем установки флага. Мне лично не понятно, зачем тебе их больше одного?

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

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)