Название: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 18:04 Делаю QTcpServer. Возникает ошибка
QObject: Cannot create children for a parent that is in a different thread. (Parent is QNativeSocketEngine(0x3ef148), parent's thread is CatTcpThread(0x3ea288), current thread is QThread(0x3e5250) Приведу код: h-фаил Код
cpp-файл Код
Т.е. ошибка в ф-ции void CatTcpThread::slot_transmiteDataForClient(QByteArray &block), а точнее вот тут m_client->write(block) как я понимаю, это из-за того, что m_client создается в другом потоке. Вопрос - как правильно переделать CatTcpThread? Создавать m_client не в run()? Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 18:19 В общем проблему решил сам
Код
Решение нашел в интернете. А теперь подскажите (не до конца понял), что делает moveToThread? Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: mutineer от Сентябрь 08, 2012, 19:16 Перемещает наследника QObject в другой тред, то есть объект теперь работает не с главным QEventLoop, а с QEventLoop треда
Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 21:39 Спасибо за ответ!
Но выходит я не правильно сделал. this->moveToThread(thread); работает, только если один клиент подключен. При подключении второго клиента, он начинает работать, что верно - теперь же для него this->moveToThread(thread); а первый выдает ошибку. А как выйти из этого положения? Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: V1KT0P от Сентябрь 08, 2012, 21:59 Спасибо за ответ! Если я правильно понял, то сперва у тебя была ошибка из-за того что ты лез в объект принадлежащий чужому треду. Ты решил это переносом сервера в тред в котором находится этот объект. Тут ты создаешь еще один объект и снова начинаешь переносить сервер в уже друго тред(это уже начинает плохо попахивать). И что же ты получаешь, ведь теперь при обращении к первому объекту получится таже ситуация что и до перемещения треда ибо сервер уже работает в треде другого объекта.Но выходит я не правильно сделал. this->moveToThread(thread); работает, только если один клиент подключен. При подключении второго клиента, он начинает работать, что верно - теперь же для него this->moveToThread(thread); а первый выдает ошибку. А как выйти из этого положения? Зачем ты делаешь это: Код Если первоначально ты делал правильно: Код Ибо если объект принадлежит треду то и вызывать его лучше из этого треда. А постоянно перемещать сервер между разными тредами я считаю не такой уж хорошей идеей. Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 22:26 Без разницы. Что emit, что циклом проходить по всем тредам - результат один и тот же.
Пока понять не могу следующее - проблема возникает тут Код
Запустил три клиента - сервер выдал на каждого клиента по одной такой ошибке... и прекрасно работал! Это как то странно... И за одно еще одна не понятка. У меня Код
когда я закрываю клиента (просто выхожу из программы), как серверу узнать, что клиента больше нет? Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 22:27 Да и конечно moveToThread была совсем не правильной идеей.
Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: V1KT0P от Сентябрь 08, 2012, 22:40 Ну смотри вот ошибка:
Цитировать Parent is QNativeSocketEngine(0x3ef148), parent's thread is CatTcpThread(0x3ea288), current thread is QThread(0x3e5250) В ней сказано что QNativeSocketEngine принадлежит потоку CatTcpThread(указатель на 0x3ea288), но вызывается из другого потока указатель которого 0x3e5250. То-есть ты вызываешь метод объекта не из того потока к которому он принадлежит.Вызывай методы CatTcpThread только через сигналы. Для того чтоб серверу знать какой клиент разорвал связь: 1) Создаешь у CatTcpServer слот который будет вызываться когда CatTcpThread разрывает связь. У CatTcpThread для этого делаешь сигнал. 2) Соединяешь сигнал CatTcpThread с слотом CatTcpServer через QSignalMapper, для того чтоб знать какой именно CatTcpThread вызвал этот слот. Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 22:48 Так я и вызываю через сигналы...
Нет, тут все не так просто. Я уже прогуглил интернет - аналогичных вопросов много, ответов - нет. Можно конечно отказаться от использования отдельных тредов для каждого соединения. Такое впечатление, что пример threadedfortuneserver из Qt только и работает так, как он там и сделан... Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: V1KT0P от Сентябрь 08, 2012, 22:53 Так я и вызываю через сигналы... Дело в том, что я сам лично делал сервер в котором каждый клиент обрабатывался в своем потоке и все работало как часы.Нет, тут все не так просто. Я уже прогуглил интернет - аналогичных вопросов много, ответов - нет. Можно конечно отказаться от использования отдельных тредов для каждого соединения. Такое впечатление, что пример threadedfortuneserver из Qt только и работает так, как он там и сделан... Но я всегда на всякий случай при коннекте указываю Qt::QueuedConnection. Попробуй и ты, может коннекты неправильно соединяются. Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 08, 2012, 23:35 Да конечно Qt::QueuedConnection пробовал в первую очередь.
В общем так - переделал без отдельных тредов Код
То, что закомментированно - как было. Без тредов работает на ура. Опять же по гуглу - все ответы на подобные вопросы сводились к этому же - делать без отдельных тредов. На сколько я понимаю, проблема здесь в том, что QTcpSocked изначально использует свою тред. Но все же очень был бы раз понять, почему с тредами не работает, если даже сами разработчики пример с тредом приводят. Хотя конечно тот пример , что у них - принципиально другой. Название: Re: QObject: Cannot create children for a parent that is in a different thread. Отправлено: Alex_C от Сентябрь 09, 2012, 00:24 Ответ найден тут
http://www.prog.org.ru/topic_9349_0.html - ключевое слово thread->moveToThread(thread); |