![]() |
Модераторы: 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 |
Суть ясна... спасибо...
|
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |