Название: БД и многопоточность Отправлено: demiurg от Сентября 18, 2011, 16:00 Незнаю где тему создать толи в БД толи в многопоточных приложениях . :)
Хочу в многопоточном TCP сервере подключаться к БД(MySQL) и сохранять данные от клиентов в неё. Появились вопросы по реализации такой структуры 1) Насколько я понял нужно создавать отдельное подключение в каждом потоке ? 2) Нужно ли именовать это подключение или же оно проименуюется по дефолту и одинаковые имена не вызовут ошибку из разных потоков? 3) Нужно ли блокировать как то БД? Или же пересечение данных из разных подключений исключается? Ну и чтобы не создавать ещё одну тему в другом разделе такой вопрос : Т.к. приложение ответственно по времени , а каждый клиент при подключении выдаёт данных не более 20 Кб и по времени не более нескольких секунд - решил выделить каждому клиенту по потоку( вопреки общественному мнениею ;D ) . Вопрос - а какой максимальное кол-во потоков выдержит сервер на WinServer2003? Т.е. сотню например он выдержит? Название: Re: БД и многопоточность Отправлено: LisandreL от Сентября 18, 2011, 17:09 1) Да.
2) Нужно уникальное имя (я включал в имя адрес потока). 3) Зависит от логики работы. Атомарные изменения нужно заключать в транзакциях. Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу. 4) Даже на не серверной винде приложение может запустить 800+ потоков. Общественное мнение не потому рекомендует не делать слишком много потоков, что ОС их не выдержит, а потому, что так вы будете терять много времени на переключение между потоками и «ответственного по времени» будет в итоге тратиться больше. Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 18, 2011, 18:01 1) Да. 2) Нужно уникальное имя (я включал в имя адрес потока). 3) Зависит от логики работы. Атомарные изменения нужно заключать в транзакциях. Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу. 4) Даже на не серверной винде приложение может запустить 800+ потоков. Общественное мнение не потому рекомендует не делать слишком много потоков, что ОС их не выдержит, а потому, что так вы будете терять много времени на переключение между потоками и «ответственного по времени» будет в итоге тратиться больше. 3) Логика простая - пришли данные, считался идентификатор, и занеслись в таблицу с заполением поля соответствующему идентификатору. Отключение от сервера. 4) Понятно , спасибо за разъяснения. Думаю не критично когда время передачи и обработки - секунды а данных и 20Кб не наберётся. Цитировать Возможно есть ещё ограничения в зависимости от системы хранения (MyISAM, InnoDB …) - точно не скажу. Вот это интересно, что лучше для таких задач. Нужно "загуглить"... Название: Re: БД и многопоточность Отправлено: LisandreL от Сентября 18, 2011, 19:51 Ах да, ещё учтите, что у MySQL есть ограничение на количество одновременных подключений (впрочем настраиваемое).
Название: Re: БД и многопоточность Отправлено: Whiplash от Сентября 19, 2011, 08:24 На Хабре как-то была статья про многопоточное приложение на Qt работающее с БД через singleton-класс. Т.е. собсно подключение одно на все потоки, которое обеспечено синглтоном в отдельном потоке. Потоки посылают ему сигналы с запросами или с параметрами запросов, а поток подключения выполняет это на БД.
Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 09:49 На Хабре как-то была статья про многопоточное приложение на Qt работающее с БД через singleton-класс. Т.е. собсно подключение одно на все потоки, которое обеспечено синглтоном в отдельном потоке. Потоки посылают ему сигналы с запросами или с параметрами запросов, а поток подключения выполняет это на БД. ууу, чо так сложно, я есчо не вырос до этого уровня. Да и если подключение одно - смысл многопоточности теряется. БД то может и 100 и 200 подключений выдерживать. А если "зависнет" поток - то основное приложение не встанет( по идее).Название: Re: БД и многопоточность Отправлено: Странник от Сентября 19, 2011, 09:59 Да и если подключение одно - смысл многопоточности теряется. БД то может и 100 и 200 подключений выдерживать. А если "зависнет" поток - то основное приложение не встанет( по идее). и почему же теряется смысл, любопытно? запросы клиентов по-прежнему обрабатываются параллельно, а запись данных в БД последовательная в любом случае. но при одном подключении вы избавляетесь от накладных расходов на подключение-отключение клиентов к БД.Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 11:24 Да и если подключение одно - смысл многопоточности теряется. БД то может и 100 и 200 подключений выдерживать. А если "зависнет" поток - то основное приложение не встанет( по идее). и почему же теряется смысл, любопытно? запросы клиентов по-прежнему обрабатываются параллельно, а запись данных в БД последовательная в любом случае. но при одном подключении вы избавляетесь от накладных расходов на подключение-отключение клиентов к БД.Да, не подумал, токма всёравно без примера не смогу реализовать :-[ У мну есть готовый многопоточный сервер- с ним я разобрался , а как реализовать этот singleton - чтото из разряда магии ;D Название: Re: БД и многопоточность Отправлено: Странник от Сентября 19, 2011, 11:38 да вот собственно упомянутая выше статься с Хабра (http://habrahabr.ru/blogs/qt_software/52536/), подробно и с примерами.
Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 11:46 Упс , да там не всё так сложно. Люблю примеры , надеюсь заработает :) (у меня ;D) Спасибо ,пойду шаманить ...
Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 19:38 Цитировать да вот собственно упомянутая выше статься с Хабра, подробно и с примерами. Попытался скомпилить этот "синглетон", но на Код: class DatabaseAccessor а если добавить макросы Q-OBJECT - говорит что незнает что такое dbHost;dbName;dbUser;dbPass; Или это пример условно рабочий? Название: Re: БД и многопоточность Отправлено: BRE от Сентября 19, 2011, 19:42 Это же хабр. :)
Что бы использовать сигналы/слоты класс должен быть наследником QObject и иметь макрос Q_OBJECT. В таком виде "декларация слотов" как бы бесполезна. Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 19:50 Это же хабр. :) Что бы использовать сигналы/слоты класс должен быть наследником QObject и иметь макрос Q_OBJECT. В таком виде "декларация слотов" как бы бесполезна. Я это предвидел , поэтому написал так Код: class DatabaseAccessor:public QObject Но тогда чёт вылазит ошибка вида undefined reference to `DatabaseAccessor::dbName' итд при попытке обращения. Вроде ж явно объявлены. Ничо не понятно... ООП не моё :-[ Название: Re: БД и многопоточность Отправлено: BRE от Сентября 19, 2011, 19:52 Статические переменные нужно определить в .cpp файле, у тебя они только декларированы.
В .cpp файле: Код
Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 20:35 Ну так я их и определял
так Код: DatabaseAccessor::DatabaseAccessor(QObject *parent) и так Код: int main(int argc, char **argv) { Ниего не меняется. Вообщем , чот сырец какой то, явно не моего уровня. А где бы найти нормальное описание создания классов , только практически а не теория... Название: Re: БД и многопоточность Отправлено: BRE от Сентября 19, 2011, 20:46 Ну так я их и определял Ты их в функции что ли определял?Код
и так А так ты им значения присваиваешь.А где бы найти нормальное описание создания классов , только практически а не теория... Рекомендую любую книгу по C++. ;)Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 19, 2011, 21:01 Цитировать Ты их в функции что ли определял? Код
Аааа....дела... Цитировать Рекомендую любую книгу по C++. ;) Да есть , читал. Всё какието примеры отдалёные от реальности. Нужна просто книга с примерами. А таких нет практически для высокого уровня, когда уже классы свои создавать надо. Каша в голове получается- проблема в том что в С++ пришёл через asm->С. Там всё явно и прямолинейно. Правда и писанины в разы больше. ЗЫ Спс, заработало, даже к базе конектица :) Название: Re: БД и многопоточность Отправлено: BRE от Сентября 19, 2011, 21:13 Каша в голове получается- проблема в том что в С++ пришёл через asm->С. Там всё явно и прямолинейно. Правда и писанины в разы больше. Поэтому и рекомендую вначале хорошо разобраться с инструментом (C++), а потом уже подходить к Qt.А на счет пути... я тоже шел по тому же пути и могу сказать что на каждом шаге есть свои тонкости. :) Название: Re: БД и многопоточность Отправлено: Denis.Rassvetniy от Сентября 21, 2011, 05:33 Цитировать Рекомендую любую книгу по C++. ;) Да есть , читал. Всё какието примеры отдалёные от реальности. Нужна просто книга с примерами. А таких нет практически для высокого уровня, когда уже классы свои создавать надо. [/quote] Рекомендую Р. Лафоре "Объектно-ориентированное программирование в C++" Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 21, 2011, 09:12 Спс. Скачал, читаю...
Я вот тут подумал. Если сделать этот синглетон, то в той его реализации после отправки запроса придётся стопорить поток msleep*ами и ждать ответа, т.е. новые данные с клиента , если и придут, то не обработаются - так а в чём тогда выигрыш? А если делать подключение к БД в каждом потоке , то всегда есть статичное время подключения к БД ( ну допустим 1-2 секунды). Или как то реализовать на сигналах и слотах. А как тогда сигнал передать именно тому объекту, от которого запрос(сигнал на запрос) пришёл ??? Название: Re: БД и многопоточность Отправлено: BRE от Сентября 21, 2011, 09:32 А если делать подключение к БД в каждом потоке , то всегда есть статичное время подключения к БД ( ну допустим 1-2 секунды). А ты используй пул потоков и для каждого потока используй свое подключение.Тогда рабочие потоки не придется пересоздавать и переподключать к БД. Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 21, 2011, 10:01 Т.е. не разрушать потоки после отключения клиентов... А при подключении связывать сигналы отключения и приёма со слотами определённого потока, выбранного из пула? Так получается? Но тогда нужно будет держать по 100 потоков( по клиенту на поток) - а сильно ли это нагрузит систему...
ЗЫ Да , видать надо было в другом разделе тему создавать... Название: Re: БД и многопоточность Отправлено: LisandreL от Сентября 21, 2011, 10:35 Но тогда нужно будет держать по 100 потоков( по клиенту на поток) - а сильно ли это нагрузит систему... Qt потоки != потоки системы. Cистемный поток существует только пока QThread находится в run.QThread до start() и после finished() из системных ресурсов потребляет только немного памяти. Название: Re: БД и многопоточность Отправлено: BRE от Сентября 21, 2011, 10:55 Т.е. не разрушать потоки после отключения клиентов... А при подключении связывать сигналы отключения и приёма со слотами определённого потока, выбранного из пула? Так получается? Но тогда нужно будет держать по 100 потоков( по клиенту на поток) - а сильно ли это нагрузит систему... Не нужно ничего разрушать и никого отключать. :)Ты сразу создаешь несколько рабочих потоков (например 4 или 10 или 25 :) ) и открываешь для каждого свое подключение. Пока работы нет, эти потоки спят. Появился запрос к БД ты кладешь его в очередь, первый свободный поток просыпается и начинает его обрабатывать. По окончании обработки запроса этот поток заснет, если других запросов в очереди нет или возьмет очередной запрос из очереди. Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 21, 2011, 11:18 Ааа, даже так... То что надо. А очередь можно реализовать перебором QList или QMap ? Т.е. переираешь теже 25 потоков и ищеш первый который свободный, например ввести переменную , которая покажет что поток свободен.
Название: Re: БД и многопоточность Отправлено: BRE от Сентября 21, 2011, 11:25 Ааа, даже так... То что надо. А очередь можно реализовать перебором QList или QMap ? Т.е. переираешь теже 25 потоков и ищеш первый который свободный, например ввести переменную , которая покажет что поток свободен. Доверь поиск свободных потоков ОС.Почитай: http://www.prog.org.ru/topic_16083_15.html http://www.prog.org.ru/topic_14426_60.html Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 21, 2011, 12:00 Хм, не уловил ,так сказать, идеи. Работать через QThreadPool?
Сейчас в принципе работает так( но пока и нет 100 подключений) Код: void EchoServer::incomingConnection(int socketDescriptor) { Это пример из Земского , для чайников ;D Мне подходит( Пока что. Но думаю метод RUN и слоты связанне с ним не поменяются) . Получается , вместо удаления потока мы просто его "освобождаем", но как это сделать -я не понял. ЧайникСсс :) А есть хотябы сырой пример? - чтобы начать "копать" ... Название: Re: БД и многопоточность Отправлено: BRE от Сентября 21, 2011, 12:42 Темы не дочитал до конца? :)
Там и примеры есть и наброски. Название: Re: БД и многопоточность Отправлено: demiurg от Сентября 21, 2011, 14:00 Дочитал вот сейчас. Стало оформляться.
Получается в основном потоке принимаю подключения и заношу в очередь( например в QList) , и шлю сигнал всем потокам , что очередь не пустая. По очереди возникают слоты, в которых обрабатываем эту очередь, изымая клиентов из очереди ( а как быть с тем что может опять возникнуть вызов) . После окончания работы(например в слоте отключения клиента от сервера) вызываем метод wait который "усыпляет поток". ТАк? Или всё же всё сложнее ? |