Название: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 17, 2010, 21:44 Сабственно вот такая проблема. Имеются клиент и сервер.
На стороне клиента выполняются два действия. 1. По нажатию 1-й кнопки отправляется инфа на сервер с некими данными и начинаются ДОЛГИЕ расчеты 2. По нажатию 2-й кнопки расчеты останавливаются на любом этапе выполнения На стороне сервера: После того как клиент приконектился к серверу и нажал на кнопку 1, создается поток в котором создается сокет принимающий инфу от клиента с данными. Дальше в зависимости от того какие данные приняты type 1 или type 2 или type 3: type 1 не рассматриваем (быстрый расчет) type 2 долгий расчет - после создания сокета создается вторичный поток в котором вызываются созданные мной класы и методы type 3 - после получения запроса с этим типом вторичный поток, сокет, первичный поток останавливаются, клиент отцепляется от сервера. При закрытии сервера - отцелпяются все присоедененные клиенты При закрытии клиента на сервер подается команда на закрытия соответствующих потоков и сокета сооедененного с закрывающимся клиентом. Код клиента непоказан, т.к. в нем все понятно. Вот код сервера, все потоки вроде закрывает как надо, но как то через Ж получилось, и зараза при закрытии (нажатии на крестик окна) вылетает с ошибкой. Запутался вообще уже блин... Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 19, 2010, 08:30 Все никак разобраться не могу ???, весь форум перерыл, никак не получается настроить сигналы и слоты правильно, мне кажется все дело в них, ведь можно же убить вторичный поток через terminate() не дожидаясь пока он закончит свою работу..., не хочу лезть в потоки через volatile bool stop = true, должен быть более правильный вариант..., я весь форум перерыл, на форуме не видел что бы моя проблема обсуждалась, как мне кажется интересно будет многим, да и в литературе ответов нет, се больше простые примерчики....
Хэлп... ;) Я подоедактировал исходники сервера, теперь он в виде последнего варианта который есть у меня..., но косяки блин те же... Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: BRE от Февраль 19, 2010, 09:05 Использовать переменную для выхода из потока лучше (правильный вариант), чем убивать его terminate, т.к. ты сам выбираешь момент завершения потока и может это сделать корректно.
Лучше сначала научиться запускать/останавливать потоки локально, т.е. без использования сети. Так будет проще разобраться. ;) Тем с описанием этого метода на форуме несколько. Не обязательно изменять значение переменной stop явно, лучше сделать в классе своего потока метод (слот) stop, который и будет это делать. По аналогии с QThread::quit, который по сути делает тоже самое, только для цикла обработки событий потока. Прямой вызов деструктора, например Mthread->~MatchThread(), не освобождает память. Нужно использовать delete Mthread. Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: niXman от Февраль 19, 2010, 09:48 Цитировать не хочу лезть в потоки через volatile bool stop = true, должен быть более правильный вариант... это и есть самый правильный вариант ;)up глянул коды. 1. переменная "type", одновременно может быть двух значений? 2. соединять сигналы/слоты внутри QThread::run(), не лучшая идея. совет: не описывайте как у вас это должно работать или как вы хотите чтоб оно работало, а опишите что требуется реализовать. т.е. постановку задачи. это скорее разрешит вашу проблему. т.к. разбираться в чужих исходниках, мало кому охота. Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 19, 2010, 10:33 Цитировать 1. переменная "type", одновременно может быть двух значений? трех, это признак, клиент отправляет данные на сервер в таком виде:- размер отправленного пакета - признак пакета type (1 необходимо выполнить быстрый расчет, 2 медленный и долгий, 3 остановить расчет посланный по соединению ранее соединение не разрывать ждать новых вариантов расчетов) - исходные данные (их много привел как вариант myListN неважно что это будет число, строка) Цитировать 2. соединять сигналы/слоты внутри QThread::run(), не лучшая идея. этот сервер я не писал сам полностью, подсмотрел как реализовано в книжке, только в ней нет многопоточности в том виде в котором мне нужно...Цитировать совет: не описывайте как у вас это должно работать или как вы хотите чтоб оно работало, а опишите что требуется реализовать. т.е. постановку задачи. это скорее разрешит вашу проблему. т.к. разбираться в чужих исходниках, мало кому охота. исходники привел потому что думал что разобраться с ними будет легче, мне кажется еслибы я просто попросил написать за меня все полностью то это в другой форум, к фрилансерам... Задача такая. Реализавать многопоточный сервер и однопоточный клиент. Клиент может посылать три типа запросов: 1. медленные расчеты (на сервер передаются данные для расчета и вызывается на выполнение одна функция) 2. быстрые расчеты (на сервер передаются данные для расчета и вызывается на выполнение другая функция) 3. третий тип запроса останавливает любые расчеты на сервере инициированные I клиентом, при этом соединение клиент сервер не рвется, сервер ждет запрос с задачей от клиента Ограничений на колличество одновременно подсоединенных клиентов и соответственно ведущихся расчетов нет. При отключении от сервера I клиента, сервер работает дальше, выполняет запросы и расчеты других подсоедененных клиентов. При отключении сервера клиентам посылается сообщение что сервер больше не работает Вот такая мне штука нужна... Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: niXman от Февраль 19, 2010, 11:28 Цитировать трех, это признак это понятно. но что, одновременно? или поочередно/попеременно?ну да ладно. попытаемся разобрать задачу по частям... Цитировать Реализавать многопоточный сервер и однопоточный клиент. Клиент может посылать три типа запросов: вот с этого и начнем.1. медленные расчеты (на сервер передаются данные для расчета и вызывается на выполнение одна функция) 2. быстрые расчеты (на сервер передаются данные для расчета и вызывается на выполнение другая функция) 3. третий тип запроса останавливает любые расчеты на сервере инициированные I клиентом, при этом соединение клиент сервер не рвется, сервер ждет запрос с задачей от клиента 1. в первых двух случаях, помимо самих данных для расчетов, передается еще и тип обработки данных. он может быть двух вариантов. обобщаем: в обоих случаях, данные передаются одинаково. я верно понял? Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 19, 2010, 12:03 я: трех, это признак
Цитировать это понятно. но что, одновременно? или поочередно/попеременно? нажал кнопку сформировать расчет быстрый, пришла инфа с типом 1 начался расчет который может успешно считаться или который можно остановить прислав тип 3ну да ладно. попытаемся разобрать задачу по частям... или нажал кнопку сформировать расчет долгий, пришла инфа с типом 2 начался расчет который может успешно считаться или который можно остановить прислав тип 3 просто у меня тип 1 или 2 так и входят в метод моего класса который должен непосредственно заениматься расчетами, т.е. пришло на сервер тип 1, я вызываю одни методы моего класса расчетов, если тип 2 то другие..., но для того что бы сервер мог считать в различных потоках и при всем притом мог останавливать расчеты мне и понадобилось реализовывать поток в потоке, мне кажется (я может и ошибаюсь) что по структуре примера который я привел задумка понятна, вот реализовать не получается... Цитировать 1. в первых двух случаях, помимо самих данных для расчетов, передается еще и тип обработки данных. он может быть двух вариантов. ну да данные и для быстрых и для медленных расчетов используются одни и те же, после получения данных и типа расчета я их использую в своем классе для вызова нужных мне методов моего класса...обобщаем: в обоих случаях, данные передаются одинаково. Код: void MatchThread::run() тоесть после того как я получил: соединение - первичный поток - сокет - вторичный поток - во втором потоке запускаю свои расчеты таким образом если мне необходимо расчеты остановить (второй поток) я могу снова послать данные из клиента сокету на остановку с типом 3 Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: BRE от Февраль 19, 2010, 12:38 Есть главный поток, в котором живет QTcpServer, ждущий подключения клиента.
Когда подключается новый клиент - сервер создает новый поток (ClientThread), который занимается обслуживанием этого соединения. При создании ClientThread, он переходит в состояние ожидания команды от клиента. Команда поступила: * расчет 1/2 - проверили, выполняется ли расчет и если да - завершили расчте (см. ниже), запустили поток (!) BuildingAThread/BuildingBThread. ClientThread - перешел в состояние ожидания команды от клиента. При завершении расчета, поток расчета отправляет сигнал в ClientThread, который возвращает результат клиенту. * завершить расчет - проверили, выполняется ли расчет (создан ли объект класса BuildingAThread/BuildingBThread и он в состоянии выполнения). Если выполняется, вызвали его метод stop, дождались когда этот поток реально завершиться (QThread::wait), разрушили объект. ClientThread - перешел в состояние ожидания команды от клиента. Клиент разорвал связь с сервером: завершили расчет (если он был запущен), запустили позднее разрушение объекта ClientThread (QObject::deleteLater). Тебе нужно сделать класс потока BuildingAThread/BuildingBThread с возможностью его остановки. Для этого лучше использовать специальный флаг, защищенный мьютексом. Этот флаг необходимо проверять в цикле расчета и когда он установлен (или сброшен) выходить из метода run. На форуме есть несколько тем, где это показано. Ну а если будут трудности, напиши. Будем постить куски кода. ;) Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: niXman от Февраль 19, 2010, 13:05 в main()
Код
использовать как псевдокод. возможно чего-то не учел... Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: niXman от Февраль 19, 2010, 13:28 а у серверной программы есть ГУЙ?
просто используя boost.asio, это очень просто решается. Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 19, 2010, 13:40 Цитировать а у серверной программы есть ГУЙ? спасибо за псевдокод !!! буду вдумывать ;Dпросто используя boost.asio, это очень просто решается. пока нет, но скорее всего будет..., аппетит приходит во время еды.. а что такое boost.asio ? Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: niXman от Февраль 19, 2010, 14:04 Цитировать а что такое boost.asio ? http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio.htmlЦитировать пока нет, но скорее всего будет... никогда не видел серверов с гуем ;Dхотя от многих слышу что такие есть! ;) Название: Re: Проблема в реализации многопоточного сервера. Прошу помощи. Отправлено: AntonUfo от Февраль 19, 2010, 15:37 Огромное спасибо за помощь, в общем то все получилось, сделал остановку вторичного потока через специальный флаг. (т.е. если флаг true заканчиваю выполнять методы расчета и выхожу из QThread::run();)
Вот пример из книги Юрия Земскова с которого собственно все и началось, только вот такой нюансик как победить ? После того как клиент приконектился к серверу и создался поток - сокет, я закрываю клиента (жму на крестик), но из списка выполняемых потоков me_threads он не удаляется, т.е. не работает метод void EchoServer::removeThread() Код: void EchoServer::removeThread(){ Вот что он про него пишет: "При получении сигнала о завершении потока выясняем, какой именно поток сгенерировал этот сигнал, ставим этот поток в очередь на уничтожение и удаляем из списка потоков" обьясните плз, что он делает "на пальцах", и почему не работает, а то получается что соединения нет, а в списке поток остается... хотя память вроде освобождает... Вот пример из книги полностью. |