Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание SSl сервера, алгоритм и проблема гонок, Опишите общеприниятые принципы 
V
    Опции темы
null56
Дата 2.12.2008, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
MAKCim
Дата 2.12.2008, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін д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 на стороне сервера, естественно, неблокирующий 

как-то так


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
null56
Дата 2.12.2008, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: нет
Всего: 12



MAKCim

Уточнюсь, как я понял это....

1) Сразу при запуске приложения я создаю 1 серверный поток и какое - то количество дочерних...
2) Дочерние потоки хранят матрицы с моими структурами, в которых я храню какую - то нужную мне информацию. Вызов epoll_wait остановит цикл проверки всей матрицы до происхождения определенного события с одним из сокетов данного потока.

Или же по матрице нужно бегать постоянно????

И второе, как  лучше организовать межпроцессное взаимодействие аккептора и рабочих потоков, чтобы иметь доступ к каждой матрице каждого потока?
PM MAIL   Вверх
MAKCim
Дата 2.12.2008, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 6
Всего: 207



Цитата(null56 @  2.12.2008,  12:23 Найти цитируемый пост)
1) Сразу при запуске приложения я создаю 1 серверный поток и какое - то количество дочерних...

да, +поток для БД

Цитата(null56 @  2.12.2008,  12:23 Найти цитируемый пост)
2) Дочерние потоки хранят матрицы с моими структурами, в которых я храню какую - то нужную мне информацию. Вызов epoll_wait остановит цикл проверки всей матрицы до происхождения определенного события с одним из сокетов данного потока.

матрица одна глобальная
доступ к ней имеют все

сначала обрабатываем состояния всех элементов (в цикле)
потом дергаем epoll
потом таймаут
потом все повторяем сначала

Цитата(null56 @  2.12.2008,  12:23 Найти цитируемый пост)
Или же по матрице нужно бегать постоянно????

постоянно, но через определенный таймаут


Цитата(null56 @  2.12.2008,  12:23 Найти цитируемый пост)
И второе, как  лучше организовать межпроцессное взаимодействие аккептора и рабочих потоков, чтобы иметь доступ к каждой матрице каждого потока? 

никак  smile 
серьезно
тут можно воспользовать принципом делегирования состояний
т. е, например, элементы в состоянии FREE игнорируются рабочим потоком, но используются аккептором
аккептор же в свою очередь игнорит все состояния кроме FREE
рабочий поток переводит элемент в состояние FREE, а аккептор - в INIT
для x86, x86-64 здесь даже не нужна синхронизация
делаем состояние 32-х разрядной переменной, инкапсулируем ее в элемент и изменяем только через =
в таком случае атомарность гарантируется, если адрес переменной выровнен по границе размера 4-х байт
а это по-умолчанию гарантируется компилятором


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
null56
Дата 2.12.2008, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: нет
Всего: 12



Суть ясна... спасибо...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0885 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.