QThread и QTcpSocket

Я сделал серьезную ошибку, когда делал какой-то проект, и теперь мне нужно перепрограммировать его снизу. Я пишу многопоточный сервер, который будет обрабатывать соединения, запросы и т. Д. Но, когда я создал новый класс с базой Объект QThread, я начинал поток с QThread-> run (), а не QThread-> start (). Теперь я получаю кучу ошибок. Здесь ситуация.
У меня есть сервер, который создает новые потоки на каждом соединении и начинает читать данные с каждого подключенного клиента. Когда я получаю данные, он испускает сигналы, которые подключены к основному классу графического интерфейса пользователя, и отображает результат ОК. Это также сохраняет дескриптор сокета для ответа на сообщения. Когда я записываю данные в сокет из класса GUI, он говорит это:

QObject: Невозможно создать дочерние элементы для родителя, который находится в другом потоке.
(Родитель — QNativeSocketEngine (0x23a6c38), родительский поток — MyThread (0x1fb8670), текущий поток — QThread (0x9eb980).

В чем дело?

0

Решение

Я знаю QT, но не очень хорошо знаком с самой реализацией сокета QT, но из звука вашего сообщения об ошибке и из-за того, как вы описываете свой дизайн, ваша проблема связана не с QT, а с архитектурой потоков / сокетов в целом. Многопоточные приложения требуют тщательного продуманного интеллектуального проектирования, чтобы быть эффективными и гарантировать, что ваши данные сеанса и т. Д. Являются согласованными и не чреваты проблемами параллелизма, потерянными структурами данных и т. Д.

Это также сохраняет дескриптор сокета для ответа на сообщения. Когда я записываю данные в сокет из класса GUI, он говорит это …:

Не зная всех деталей вашей реализации, если вы сохранили дескриптор сокета в потоке 1 для ответа на вызов в потоке 1, а затем попытались записать в него данные из вызова с использованием потока 2, этот оригинальный дескриптор сокета недопустим в контекст темы 2. Это может объяснить ваше сообщение об ошибке.

Сохранение дескриптора сокета для последующих вызовов не является хорошим способом сделать что-либо по ряду причин (включая проблему, с которой вы столкнулись.) Почему вы это делаете? Если вам необходимо сохранить информацию о клиенте при вызовах, используйте структуры сеансов для сохранения этих данных. Если вы хотите сохранить весь поток живым, пока разговор продолжается, спроектируйте свои взаимодействия потоков / сокетов таким образом, чтобы они учитывали пул потоков и т. Д. Но вы не должны иметь потерянных сокетов, просто торчащих вокруг — каждый должен существовать в имеет собственный контекст потока и не имеет действительного дескриптора вне своего «домашнего» потока.

Когда сокет завершает свой диалог, поток, который был создан, и сокет, созданный в этом потоке для продолжения диалога, ГОТОВ — он должен ВСЕМ быть очищен.

Если я правильно понимаю вашу реализацию, мои предложения должны решить вашу проблему.

В своем комментарии вы упоминаете:

«сокет как глобальная переменная» — вы НЕ должны использовать глобальный сокет таким образом, если я правильно понимаю, что вы делаете.

В вашем серверном приложении должен быть основной поток с постоянным сокетом, который прослушивает запросы. Когда вы получаете входящий запрос, должен быть излучен сигнал, а слот для этого сигнала должен порождать поток, который инициализирует новый сокет для обработки этого запроса. Обработайте запрос в ветке, затем все почистите и т. Д.

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

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

Короче говоря: «Что происходит в потоке, остается в потоке»

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]