Евгений Якушов, Я вот про это и говорю. Постараюсь объяснить. Если ваш код выглядит так, то что происходит.
void someFunc(){
ModuleRls RLS = ModuleRls(x, y, r);
model.Start(RLS);
}
Создается объект RLS и начинают стартовать потоки, пока все хорошо. Но при выходе из функции model.Start(RLS) RLS удаляется, и потоки начинают общаться с удаленной памятью, а это UB. В том месте где раньше был объект RLS может находиться любой мусор. Скорее всего у вас так и происходит.
Евгений Якушов, кто отвечает за хранение и время жизни RLS? Хранится ли в каждом классе копия или они общая для всех. Видно что в Start передается по ссылке, но не видно, как передается в конструктор StreamFly и каким образом вдруг становится указателем. Покажите конструктор StreamFly принимающий его.
Очевидная проблема может быть в том, что RLS уже удален, во время вызова метода run, либо кто-то меняет переменную во время чтения.
Может ли измениться переменная state.x пока StreamFly запущены?
Советую добавить хотя бы интерфейс класса StreamFly. И код запуска старт. Вообще не понятно, когда удаляется ModuleRls, копируется ли она в StreamFly, меняет ли ее кто-то. Что происходит с памятью после старта тоже непонятно, ведь нет кода. Вывод как раз таки особо информации в себе не несет, просто видно что какой-то мусор.
Михаил Main, Всегда придется хоть что-то дописывать. Правая часть выражения вычисляется не смотря на тип в левой части. Получается, если в тупую смотреть, сначала идентифицируется переменная float a, потом вычисляется выражение с двумя переменными 1 / 3 (так как обе переменные int то и результат будет int), потом выполняется присваивание результата выражения переменной. И все эти три этапа независимы друг от друга.
Если типы будут разные, то тогда уже будет проведено приведение типов. Но обычные цифры это тип int.
Куда вам точнее надо? Ваш пример не описывает проблемы. Чем вас в первом случае не устраивает ответ? Могу сказать, что double точнее представляет числа, но сомневаюсь, что такой ответ вам подходит. То, что вы мыслите в десятичной системе не значит, что двоичная неточная.
И советую вам оформить код в тег code . Читать сложновато скриншоты.
Sazoks, так в этом то и прикол, что у сокетов различные буферы для записи и чтения. Тоесть чтобы отправить вы пишете в одно место, а читаете из другого.
А в пределах вашей программы это не может одновременно произойти , так как у вас будет один поток и в единый момент времени вы либо читаете, либо пишете, одновременно никак.
Если прямо хочется обрабатывать сообщения в другом потоке, то можно просто само сообщение и обрабатывать, а не создавать сокет и читать из него. Пусть исходный сокет так и читает данные и просто сигналит о чтении, посылает сообщение в другой поток.
Я на всякий случай уточню, вполне возможно, что не могут существовать два QTcpSocket-а с одинаковым дескриптором, так как они читают из него в свой локальный буфер и поэтому до второго не доходят данные, но не уверен в подобной реализации. Опять же чтение из одного дескриптора из разных потоков не факт что безопасно.
Да и qt не советует использовать QTcpSocket в потоках, так как он условно асинхронный.
Либо второй вариант, проблема может быть в потоке и его eventLoop.
Sazoks, я про это и говорю, в главном потоке вы создаете connect, который читает данные в исходный сокет, потом создаете второй, но connect остается, так ведь? И получается что исходный сокет читает все данные и второму ничего не остается. Метод connect возвращает QMetaObject::Connection с помощью которого потом можно сделать disconnect для исходного сокета от сигнала readyRead. Либо я до сих пор не понял в чем проблема.
Вы же сами подключаете сигналы к слотам, просто одним сокетом читайте, другим пишите. Так же у QAbstrackSocket в метод connectToHost передается флаг, можно выбрать хотите вы только читать или только писать.
Мне кажется, что у вас тут проблема как минимум с тем, что функция делает слишком много(кастует, читает, потом еще пишет) и из-за этого применимость, гибкость ее и вообще читаемость сильно падает. Через несколько месяцев вам же самому будет трудно читать и отлаживать такой код, даже если кол-во таких методов не вырастет.
Не уверен, что хорошо это советовать, так как в c++ функциональный код особо не читаем, но избавиться от подобного можно с помощью связывания. Про это говорится с минуты 15, но лучше все посмотреть. Так у вас будет несколько мелких функций, которые тупо легче читать и один класс который это все свяжет. Довольно гибко, но на любителя.
А по поводу обучения, так с этим так же как и везде, практиковаться и решать проблемы.
Евгений Шатунов, ок, не правильно выразился, main быть может, как может и не быть. Просто по мне это немного усложняет логику использования библиотек, либо если добавить две таких статических библиотеки может возникнуть казус. И вроде, в среднем, так не делают. Заставить пользователя инициализировать что-либо перед выполнением можно менее извращенными способами.
Раз используете значение возвращаемое функцией recv, то стоило бы его проверять на валидность, может станет более понятно в чем проблема.
Опять же может возникнуть проблема, что в клиенте вы просто читаете раньше чем пишете на сервере. Recv возвращает только доступные на данный момент данные.
И из заголовка не до конца понятно, 0 у вас все-таки только j или вообще весь буффер в который вы читаете.
Если вы будете делать join для каждого клиента, нужен ли вам отдельный поток вообще?
Либо другая проблема, при maxclients > 1, что будет происходить? Фактически пока все сессии не завершатся остальные потоки будут ждать до последнего. Было бы логичнее если при отключении одного клиента мог бы подключиться другой.
Создается объект RLS и начинают стартовать потоки, пока все хорошо. Но при выходе из функции model.Start(RLS) RLS удаляется, и потоки начинают общаться с удаленной памятью, а это UB. В том месте где раньше был объект RLS может находиться любой мусор. Скорее всего у вас так и происходит.