![]() |
|
Модераторы: xvr |
![]()
|
|
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
Здравствуйте!
Хочу создать игровой сервер. Есть не малый опыт программирования на С/С++. Никогда не писал сетевые программы, и тем более многопользовательские сервера. Читаю это: http://rapidshare.com/files/287978995/Shon..._Linux.pdf.html Купил http://www.ozon.ru/context/detail/id/3961491/, еще заказал http://www.ozon.ru/context/detail/id/2355792/ Попробовал написать простой клиент и сервер по кодам из книжки, работает. Меня больше интересует, как обрабатывается множество соединений одновременно? То что нужно синхронизировать доступ к общим данным, понимаю, полагаю использовать pthread(http://ru.wikipedia.org/wiki/POSIX_Threads). С принципами многопоточности/синхронизации знаком, использовал не мало. В книжке(http://rapidshare.com/files/287978995/Shon_Uolton_-_Sozdanie_setevih_prilojenii_v_srede_Linux.pdf.html) в качестве примера приведен пример сервера использующего accept(). Но, как я выяснил, вычитывая статьи из инета, это очень старый способ, есть нечто более новое, poll, и еще по новее epoll. Так вот epoll описывается в этой(http://www.ozon.ru/context/detail/id/3961491/) книжке. Но только вызовы. Никакой информации о проектировании сервера с использованием epoll нет. Вот собственно и сама просьба, наставьте на путь истинный. Подскажите, что нужно делать, и как? Как проектировать сервер, что нужно знать для проектирования, ... и еще много вопросов о которых я еще не знаю. Всем откликнувшимся, много благодарен! Это сообщение отредактировал(а) niXman - 3.10.2009, 05:01 --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
архитектура
1) поток 1 а) дергает accept() б) если в а) получили сокет, создаем (берем из кэша) дескриптор клиента и помещаем его в очередь в) переход на а) 2) поток 2 выполняет бесконечный цикл а) выполняет list_replace_init на очереди клиентских дескрипторов б) циклически просматривает матрицу элементов выполнения в) если поле состояния элемента - COMPLETE, освобождаем все данные, связанные с ним, берем дескриптор клиента (если он есть), связываем его с элементом выполнения, переводим его в состояние READY; если состояние элемента - FREE, значит он никем не используется, выполняем аналогичные действия кроме освобождения данных (освобождать нечего) 3) потоки 3...N, где N пропорционально числу процессоров а) циклически просматривают свою часть матрицы, в соответствии с состоянием конкретного элемента выполнения, выполняются специфичные действия для него, в состоянии READY кроме всего прочего добавляем (epoll_ctl()) сокет клиента в дескриптор epoll текущего потока б) после выполнения цикла, дергает epoll_wait() в) обрабатываем события, возвращенные в б), в соответствии с состоянием каждого элемента выполнения (к примеру, если у нас SMTP сервер , текущее состояние элемента выполнения SMTP_RCPT и получили событие EPOLLIN, то читаем из сокета данные; если в полученном буфере находим "\r\n", переходим в состояние SMTP_RCPT_RESPONSE; далее в а) на следующей итерации будет отправлен ответ на RCPT команду SMTP клиента) Добавлено через 2 минуты и 56 секунд соответственно на этой схеме запросто реализуется взаимодействие с внешними менеджерами типа менеджера БД т. е если нам надо послать запрос в базу, формируем запрос и добавляем его в очередь менеджера, при этом состояние элемента выполнения сохраняем (сокет и пр. _важные_ для восстановления данные), элемент выполнения освобождаем для возможного другого клиента -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
--------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
niXman,
не обязательно я просто привел одну из схем распараллеливания для достижения масштабируемости и модульности при минимуме использования механизмов синхронизации вполне возможно совместить 1) и 2) причем как в main, так и в отдельном потоке (и даже процессе) все зависит от конечной цели -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
MAKCim, Ок. Сейчас пишу свое видение, более детальное. Выложу. Проверите.(если не затруднит)
--------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
1. количество потоков в ОС ограниченно. Наверное будет правильней, чтоб одни поток обслуживал не одного клиента. В этом случае меньше расходов на синхронизацию. 2. что подразумевается по словом "процессоров" ? --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
объекты, которые могут независимо выполнять код
ну, а я что сказал? ;) если процессоров в системе, допустим, 4, то резонно создать 8 потоков: по одному на каждый процессор + 1 дополнительный с учетом эффективной реализации шедулера в ОС -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
Все, понял. А я подумал что речь идет о процессах(или потоках). Добавлено через 4 минуты и 41 секунду
Т.е. по потоку на ядро? Если да, то как можно создать поток именно на определенном ядре? Я думал что ОС сама принимает решение об этом. Это что такое? --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
это и подразумевалось, в смысле, что если тупо создать 4 потока, то ОС в большинстве случаев распределит их по имкющимся процессорам равномерно тем не менее есть linux-specific API функция sched_setaffinity это значит, что если планировщик задач ядра ОС реализован грамотно, то выбор процесса и переключение контекста на него осуществляются с минимальным оверхедом, в этом случае увеличение нагрузки на один процессор (увеличение числа потокв) до некоторого предела даст лучший результат, нежели концентрация большего количества работы в одном потоке -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
А если потребуется 5000 клиентов? ОС наверняка столько потоков не позволит создать. --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
niXman,
где я говорил, что нужно 5000 потоков для 5000 клиентов? я говорил о _пропорциональном_ числу процессоров числе потоков в большинстве случаев это 2x, т. е. 1 проц. - 2 потока, 2 проца - 4 потока и т. д. вы читали мой первый пост вообще? -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
--------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
Имеется ввиду это? : http://crona-dev.net/index.php/mcdatatypes/mistructlisthead http://rflinux.blogspot.com/2009/05/linux.html Т.е. это просто список, или он чем-то принципиально отличается? Что подразумевается под "матрица элементов выполнения" ? Это сообщение отредактировал(а) niXman - 6.10.2009, 00:28 --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
да использование по началу не совсем очевидно ;) здесь элементы не добавляются в список, а уже являются членами списка пример
массив массивов каждому из потоков 3...N соответствует свой индекс в нем => каждый из потоков работает со своей частью матрицы -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| niXman |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 4.7.2009 Репутация: 1 Всего: 0 |
При подклучении <linux/list.h> получаю такие ошибки:
Дело в том, что каталог linux есть в /usr/include, но в нем нет файла list.h. По этому я подключил каталог /usr/src/linux-headers-2.6.28-15/include Я правильно делаю? Или файл list.h должен находится в /usr/include/linux ? Добавлено через 49 секунд OS: ubuntu-9.10 --------------------
if ( !c++ ) { *power--; this->wussiness += 10;} |
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |