![]() |
|
Модераторы: feodorv |
![]()
|
|
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
Задача: создание сервера, который будет ожидать соединения по SSL, аутентифицировать клиента, проверять его права доступа, читая их из базы (mysql, postgresql).
ОС: linux Почитав на форуме различные способы создания, так и не понял общего эффективного решения. Но, как видно, все ссылаются на использование select для слежения за сокетами и создание второго потока, а то и к совокупности между ними. Хочу привезти алгоритм моего понимания на основе прочитанного (работа только серверной): 1) Сервер висит в ожидании запроса на соединение 2) При запросе на соединение сервер в случае успешной аутентификации добавляет сокет в массив SELECT и в цикле начинает следить за состоянием каждого из сокетов и это в каком - то дочернем потоке, потому что в основном потоке приложение будет висеть в ожидании подключений accept 3) При запросе со стороны клиента (передача условной команды, допустим чтение данных из базы), это событие регистрируется через SELECT и создается ЕЩЕ один поток для этого сокета, в котором осуществляется какое - либо действие с базой???!!! 4) По завершению работы потока сокет продолжает отслеживаться через select и при необоходимости закрыт, уже в основном потоке Вопрос: Как совместно реализовать взаимодействие select и accept для работы сервера и правильно ли я это понимаю? Если эти суждения по созданию верны, то тогда как решают следующую проблему? У меня возникает такое несколько, возможно, одновременно выполняющихся задач с базой данных и возникает проблема гонок... кто первый запишет, а кто первый считает... Один записал, другой считал... эти проблемы как - нибудь решаются? Если в описании моего алгоритма работы сервера есть недочеты, пожалуйста опишите их здесь Заранее благодарен за помощь Это сообщение отредактировал(а) null56 - 2.12.2008, 10:05 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
null56,
во-первых, если ОС Linux, то не select нужно использовать, а epoll во-вторых, общий принцип следующий 1 поток - аккептор (вызывает accept), остальные N - рабочие (1 <= N <= K * CPU), CPU - количество процессоров, K - произвольный множитель (зависит от того, как эффективно реализован шедулинг в ОС) каждый рабочий поток работает со своей матрицей определенного размера (зависит от производительности процессора) каждый элемент матрицы инкапсулирует все необходимое для взаимодействия с клиентом принцип работы рабочего потока: проходит по всем элементам матрицы и вызывает функции, которые соответствуют состояниям элементов (конечный автомат) после этого вызывает epoll_wait для всех сокетов клиентов, которые соответствуют этому потоку epoll_wait возвращает набор событий, он их обрабатывает и заного повторяет весь цикл задача потока аккептора - дергать accept, находить свободный элемент в какой-либо матрице (желательно это делать с умом, чтобы равномерно нагрузить систему), устанавливать состояние элемента в INIT рабочий поток, проходя по матрице, видит, что элемент находится в состоянии INIT, добавляет его в свой epoll для работы с SSL настоятельно рекомендую использовать либу openSSL что касается взаимоодействия с мускулом, то наилучшее решение, имхо, отдельным тредом поддерживать кэш соединений к базе, чтобы по возможности избежать блокирования на коннекте к базе а еще лучше, использовать неблокирующий I/O для взаимодействия с mysql сейчас точно не скажу, поддерживается ли он нативно в libmysql если нет, надо пропатчить либу да, забыл сказать, весь I/O на стороне сервера, естественно, неблокирующий как-то так -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
MAKCim,
Уточнюсь, как я понял это.... 1) Сразу при запуске приложения я создаю 1 серверный поток и какое - то количество дочерних... 2) Дочерние потоки хранят матрицы с моими структурами, в которых я храню какую - то нужную мне информацию. Вызов epoll_wait остановит цикл проверки всей матрицы до происхождения определенного события с одним из сокетов данного потока. Или же по матрице нужно бегать постоянно???? И второе, как лучше организовать межпроцессное взаимодействие аккептора и рабочих потоков, чтобы иметь доступ к каждой матрице каждого потока? |
|||
|
||||
| MAKCim |
|
||||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 6 Всего: 207 |
да, +поток для БД матрица одна глобальная доступ к ней имеют все сначала обрабатываем состояния всех элементов (в цикле) потом дергаем epoll потом таймаут потом все повторяем сначала постоянно, но через определенный таймаут
никак серьезно тут можно воспользовать принципом делегирования состояний т. е, например, элементы в состоянии FREE игнорируются рабочим потоком, но используются аккептором аккептор же в свою очередь игнорит все состояния кроме FREE рабочий поток переводит элемент в состояние FREE, а аккептор - в INIT для x86, x86-64 здесь даже не нужна синхронизация делаем состояние 32-х разрядной переменной, инкапсулируем ее в элемент и изменяем только через = в таком случае атомарность гарантируется, если адрес переменной выровнен по границе размера 4-х байт а это по-умолчанию гарантируется компилятором -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
||||
|
|||||
| null56 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 721 Регистрация: 19.3.2008 Репутация: нет Всего: 12 |
Суть ясна... спасибо...
|
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Сети | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |