2013-02-16 8 views
0

У меня есть многопоточный сервер (наследует QTcpServer). Когда появляется новое соединение, я создаю новую задачу (наследует QRunnable), передавая дескриптор сокета в конструктор и помещая это задание в QThreadpool (есть 3 сотрудника).Ошибка приложения Qt при удалении выполненной задачи

QThreadPool::globalInstance()->start(task); 

В перспективе() я динамически создавать QTcpSocket, установить дескриптор сокета и чтения первого принятого байта. Основываясь на значении этого байта, я создаю новую конкретную задачу (также наследует QRunnable), передавая ее указатель ctr на ранее созданный объект QTcpSocket, а также нажимает эту задачу на QThreadpool.

Эта специальная задача делает некоторые рутинные и приложения сбоями. Из файла журнала я вижу деструктор этой конкретной задачи.

Также Qt Creator бросает следующее сообщение об ошибке:

QObject: Невозможно создать ребенок для родителей, который находится в другом потоке. (Родитель QNativeSocketEngine (0x18c62290), поток родителей является QThread (0x18c603e0), текущий поток QThread (0x18cc3b60) QSocketNotifier: гнездо оповещатели не может быть отключен от другой нити отказа ASSERT в QCoreApplication :: SendEvent: «Не удается отправить события на объекты принадлежит другому потоку. Текущий поток 18cc3b60. Receiver «» (типа «QNativeSocketEngine») был создан в потоке 18c603e0" , файл ядра/qcoreapplication.cpp, строка 420

Я нашел подобные сообщения, но, к сожалению, я не мог понять, как исправить мою проблему. Пожалуйста, помогите мне.

ответ

1

Вы не можете использовать QTcpSocket от tw o разные потоки, потому что QObject s не являются потокобезопасными.

Вы создали свой QTcpSocket в первой задаче, поэтому он «живет» в потоке, связанном с этой задачей. Если вы передадите свой указатель в другой QRunnable, то второй поток попытается получить к нему доступ, что приведет к поломке вещей.

Вам нужно будет отредактировать свое приложение таким образом, чтобы не делиться одним и тем же QTcpSocket между различными потоками. Одна из возможностей - реализовать различные конкретные функции в исходной задаче и просто выбрать соответствующую функцию на основе первого полученного байта

+0

Спасибо за помощь. Перед публикацией вопроса я реализовал свое приложение так, как вы посоветовали. Он работает хорошо, но выглядит ужасно, потому что в будущем я планирую добавить много задач. И если я использую определенный подход к функции, в один момент моя оригинальная задача станет слишком толстой. Поэтому я решил обратиться к сообществу за лучшими решениями. – Den

+0

Но это довольно странно. В первой задаче я делаю QTcpSocket * socket = new QTcpSocket; Таким образом, я хотел бросить этот сокет между задачами. И я понял. Я читаю первый байт в исходной задаче, создаю другую задачу и передаю ей указатель сокета, после чего ничего не делаю с завершением задачи сокета. Во второй задаче я отправляю через этот сокет тестовое сообщение в клиентское приложение. Клиент получает эту почту. Но тогда я делаю «delete socket»; во втором деструкторе задачи мое приложение падает. – Den

+0

Даже если вы не делаете ничего другого в сокете, он по-прежнему обрабатывает события внутри. – JKSH

Смежные вопросы