14 / 14 / 2
Регистрация: 18.07.2012
Сообщений: 79
|
||||||
1 | ||||||
Сокеты и QThread - как корректно завершить поток07.07.2014, 08:32. Показов 13680. Ответов 29
Метки нет (Все метки)
Пишу клиент с использованием QTcpSocket. Вынес разбор принимаемых сообщений в отдельный поток, но из-за заморочек с объектами qt никак не соображу как корректно его завершить. К тому же не отправляются сообщения из других потоков. Буду благодарен если кто подскажет как наиболее корректно построить такую конструкцию.
Код клиента: Кликните здесь для просмотра всего текста
0
|
07.07.2014, 08:32 | |
Ответы с готовыми решениями:
29
Как правильно завершить поток QThread и выйти из него? Как корректно завершить поток Как корректно завершить COM порт? Как корректно завершить чужое приложение? |
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
|
||||||
07.07.2014, 17:15 | 2 | |||||
1) не нужно предопределять run(), почитайте про moveToThread().
2) если будете использовать moveToThread(), то поток завершаем так:
3) Сигналы у вас не работают так как при наследовании run() нужно вручную запускать цикл событий, по умолчанию его нет.
0
|
07.07.2014, 17:23 | 3 |
ну желательно "атомарную" а не булеву.
И если нужно "резко" останавливать поток то вероятно все таки через определение через run(), ибо через цикл сообщений все не пустишь
0
|
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
|
|
07.07.2014, 17:26 | 4 |
Avazart, будет небольшой прирост производительности, и только, если не ошибаюсь.
0
|
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
|
|
07.07.2014, 17:35 | 6 |
0
|
07.07.2014, 17:44 | 7 |
Значит не тот код смотрели, но в теории атомарный или с крит секцией,мютексом.
C потоками можно долго не замечать... Как я понимаю можно сделать так: 1. В основном потоке создать сокет. 2. В основном потоке создать "рабочий" класс который будет обрабатывать примем данных (со слотами соотвующими) 3. В основном потоке создать класс QThread и через moveToThread() передать "рабочий" класс в него. 4. Связать сигналы сокета и "рабочего" класса через эвент луп потока.
0
|
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
|
|
07.07.2014, 18:02 | 8 |
В сорцах Qt тоже обычно bool. Хотя там попадается и ужас, который они сам не советуют использовать, типа moteToThread(this).
В общем про то что bool плох для остановки потока я ни разу не слышал. Можете поделится ссылкой на объяснение?
0
|
07.07.2014, 18:18 | 9 |
Да что там объяснять bool теоретически может быть не атомарным, кроме того он может оптимизироваться компилятором, поэтому иногда советуют заменять на volatile unsigned char, но как бы и это не гарантировано, поэтому и лучше или атомарные типы из нового стандарта или родные Qt-тишные или защита через объекты синхронизации (флаг окончания - разделяемый ресурс)
Добавлено через 9 минут Насчет bool https://www.cyberforum.ru/post3370373.html
0
|
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
|
|
07.07.2014, 18:30 | 10 |
Avazart, нда, забавно. Где-то читал что gcc сам оборачивает перемененные потока в мютексы.
0
|
07.07.2014, 18:49 | 11 |
Ну тут когда такие проверки частые идут через объекты синхр. черевато потерей скорости.
Добавлено через 17 минут Вот в этой книге вроде видел моменты с остановкой потока и о использовании QThread Qt4.7+. Практическое программирование на C++ Андрей Боровский Почитать частично можно тут http://books.google.ru/books?i... &q&f=false стр 176 - пример с QAnatomicInt
1
|
14 / 14 / 2
Регистрация: 18.07.2012
Сообщений: 79
|
||||||
08.07.2014, 06:45 [ТС] | 12 | |||||
Avazart, переписал под сигналы/слоты. Проблема с зависанием потока исчезла. Но теперь в дебаге вижу QSocketNotifier: socket notifiers cannot be enabled from another thread и программа падает при попытке дисконнекта из основного потока с "ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 506a68. Receiver '' (of type 'QNativeSocketEngine') was created in thread 5449a0"
Код: Кликните здесь для просмотра всего текста
0
|
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
|
|
08.07.2014, 07:38 | 13 |
Сложно и местами (про разницу в завершении потока в С и С++) спорно. Приостановка рабочего цикла потока элементарно делается через ожидание мютекса с таймаутом. Выход из цикла - через атомарную переменную, или через bool с синхронизацией доступа.
Как именно выглядит попытка? вызов метода disconnectFromHost() ?
0
|
14 / 14 / 2
Регистрация: 18.07.2012
Сообщений: 79
|
|
08.07.2014, 08:01 [ТС] | 14 |
uglyPinokkio, да, с дисконнектом косяк, проблема была в вызове из основного потока, переделал под слот и все стало работать нормально, но проблема с QSocketNotifier никуда не делась и вылезает при чтении/записи.
0
|
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
|
|
08.07.2014, 10:49 | 16 |
Поток в состоянии ожидания процессорного времени не получает. По крайней мере под Win.
Добавлено через 8 минут Что-то тоже без идей. read-то должен бы работать.
0
|
14 / 14 / 2
Регистрация: 18.07.2012
Сообщений: 79
|
|
08.07.2014, 11:46 [ТС] | 17 |
uglyPinokkio, пришлось отказаться от наследования QThread и сделать дополнительный класс Connection, который находится в том же потоке что и сокет и является посредником во всех вызовах, пробрасывая сигналы класса Client. По мне так слишком витиевато, но ничего лучше на просторах сети я пока не нашел, только множество подобных веток на форумах без каких либо конкретных рекомендаций.
0
|
327 / 230 / 55
Регистрация: 30.05.2014
Сообщений: 682
|
|
08.07.2014, 11:51 | 18 |
Я сам примерно так и делаю . Но IMO - тот вариант тоже имеет право на существование.
0
|
14 / 14 / 2
Регистрация: 18.07.2012
Сообщений: 79
|
|
08.07.2014, 11:58 [ТС] | 19 |
uglyPinokkio, неужели нет более удобного и изящного способа? Ведь при таком подходе приходится фактически дублировать сигналы и слоты в нескольких классах...
0
|
08.07.2014, 12:05 | 20 |
Будет время, надо будет попробовать.
0
|
08.07.2014, 12:05 | |
08.07.2014, 12:05 | |
Помогаю со студенческими работами здесь
20
Как завершить поток? Как завершить поток Как из одной программы корректно завершить другую? Как корректно завершить вывод отчета в Excel? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |