Название: QTcpSocket::readAll() SIGSEGV Отправлено: RedDog от Сентябрь 02, 2015, 12:54 В TCP сервере сокет пускается в отдельном потоке:
Код: void CSocketThread::run() Код: void CSocketThread::on_dataReceived() Вот в самом сервере создается поток для сокета. Код: void CTcpServer::incomingConnection( qintptr handle ) При чтении из сокета возникает SIGSEGV. Вылетает в случайном порядке. По объему данных никакой корреляции не увидел. Крайний раз bytesToRead = 608 ЧЯДНТ? PS: Qt 5.3.0 Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: kuzulis от Сентябрь 02, 2015, 13:30 Цитировать ЧЯДНТ? Переменная QTcpSocket живет в потоке CSocketThread::run(), но bytesAvailable() и read() выполняются из главного. ЗЫ: Ну сколько же раз будут еще такие темы подниматься? Самому проверить и подумать не судьба? Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: RedDog от Сентябрь 02, 2015, 13:40 Переменная QTcpSocket живет в потоке CSocketThread::run(), но bytesAvailable() и read() выполняются из главного. Тогда встречный вопрос: как сделать что бы они в том же потоке выполнялись?Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: torwig от Сентябрь 02, 2015, 14:04 В потоке, в котором создаете сокет, делаете все connect() и слоты там же пусть отрабатывают. Абсолютно всю работу с сокетом выносите в тот поток, где он был создан.
Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: RedDog от Сентябрь 02, 2015, 14:17 В потоке, в котором создаете сокет, делаете все connect() и слоты там же пусть отрабатывают. Абсолютно всю работу с сокетом выносите в тот поток, где он был создан. Так у меня так все и сделано. В run() создаю сокет, там же делаю коннекты к слотам.Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: qate от Сентябрь 04, 2015, 12:07 ЧЯДНТ? наследуешся от qthread ? https://wiki.qt.io/Threads_Events_QObjects Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Bepec от Сентябрь 04, 2015, 14:13 qate поясните пожалуйста.
Возможно человек просто не знал, что при наследовании от QThread необходимо в конструктор добавлять moveToThread(this), дабы слоты и остальные ф-ции принадлежали потоку, а не оставались в потоке родителя. Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: qate от Сентябрь 04, 2015, 15:11 qate поясните пожалуйста. я имел ввиду, что методика не наследоваться от qthread описано в http://doc.qt.io/qt-5/qthread.html чем плох moveToThread(this) не могу сказать Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Авварон от Сентябрь 04, 2015, 15:58 чем плох moveToThread(this) не могу сказать Код: It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Авварон от Сентябрь 04, 2015, 16:00 чем плох moveToThread(this) не могу сказать Код: It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). Типа после moveToThread(this) у вас контрроллер треда (QThread) будет жить в треде, к-ый он контролирует и, по-хорошему, все его ф-ии (quit/wait) надо будет звать из этого потока. Типа если будете дергать из главного потока, то работать будет, но некошерно. Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Bepec от Сентябрь 04, 2015, 17:31 Столько копий было сломано, но в результате вывод - это равнозначные методы применения :)
Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: RedDog от Сентябрь 07, 2015, 09:09 И все равно не понимаю...
Объект создал в потоке, подконнектил его там же. Так почему слоты вызываются в другом потоке то? Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Igors от Сентябрь 07, 2015, 09:50 И все равно не понимаю... Потому что так работает Qt::AutoConnectionОбъект создал в потоке, подконнектил его там же. Так почему слоты вызываются в другом потоке то? Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: RedDog от Сентябрь 07, 2015, 10:56 Потому что так работает Qt::AutoConnection Однако, у меня Qt::QueuedConnectionНазвание: Re: QTcpSocket::readAll() SIGSEGV Отправлено: kuzulis от Сентябрь 07, 2015, 11:21 Цитировать Qt::QueuedConnection Все верно в этом случае - слот будет вызван из главного потока приложения. Можно попробовать задать DirectConnection (я не уверен что это правильный путь), но тогда придется "защищать" прочитанные данные tmp, если планируется их передавать в основной поток: Код
Название: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Igors от Сентябрь 07, 2015, 11:25 Потому что так работает Qt::AutoConnection Однако, у меня Qt::QueuedConnectionНазвание: Re: QTcpSocket::readAll() SIGSEGV Отправлено: Bepec от Сентябрь 07, 2015, 14:18 В конструкторе своего отнаследованного от QThread класса вставьте строчку moveToThread(this) и будет вам счастье.
|