Название: Threadedfortuneserver - добавить чтение клиентского сообщения. Отправлено: Last от Март 21, 2013, 13:22 Всем привет, суть проблемы в названии (threadedfortuneserver - пример из дистрибутива Qt). В моей текущей реализации ответ клиенту приходит, но сервер сразу после этого падает. Отладчиком найти место падения не получается, т.к. оно происходит где-то в дизассемблированных кодах, в коих я ничего не понимаю.
Мой вариант thread.h: Код: class Thread : public QThread Код: void Server::incomingConnection(qintptr socketDescriptor) Код: void Thread::run() Ошибки из Application Output Цитировать QSocketNotifier: socket notifiers cannot be enabled from another thread Я понимаю, что эти ошибки связаны с наличием tcpSocket'a в классе треда. У меня своего рода дилемма: если убрать tcpSocket из класса треда, то сигнал readyRead() вызовется один раз, после чего тред просто повиснет и клиент не получит ответа, а если tcpSocket не убирать, приложение вообще падает с ASSERT FAILURE.QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0x12ba6e40), parent's thread is Thread(0x12ba80e0), current thread is QThread(0x12b3e0b0) QSocketNotifier: socket notifiers cannot be disabled from another thread ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 12b3e0b0. Receiver '' (of type 'QNativeSocketEngine') was created in thread 12ba80e0", file kernel\qcoreapplication.cpp, line 420 Invalid parameter passed to C runtime function. Invalid parameter passed to C runtime function. QNativeSocketEngine::waitForWrite() was called on an uninitialized socket device Подскажите пожалуйста, если есть идеи, как можно выбраться из такой ситуации. Название: Re: Threadedfortuneserver - добавить чтение клиентского сообщения. Отправлено: k0p4 от Март 21, 2013, 15:31 Цитировать Thread *thread = new Thread(socketDescriptor, fortune, this); Трэд был создан и висит в главном потоке. Соккет - член класса трэд. Значит тоже висит в главном. Метод run() выполняется в параллельном потоке. Отсуда и проблемы. Сделай moveToThread для соккета.Вообще в методе run() должен быть только exec();. Т.е, запускаем локальный ивентлуп трэда, для получения ивентов. При этом incomingConnection будет выглядеть примерно так: Код: void Server::incomingConnection(qintptr socketDescriptor) А всю обработку вместо трэда вынести в класс соккета. Название: Re: Threadedfortuneserver - добавить чтение клиентского сообщения. Отправлено: Last от Март 24, 2013, 23:00 Спасибо, уже раскурил маны с подачи людей, сидевших в IRC.
|