Лучший подход для написания Linux Server на C (phtreads, select или fork?) - PullRequest
8 голосов
/ 02 апреля 2012

У меня очень специфический вопрос о программировании сервера в UNIX (Debian, ядро ​​2.6.32).Моя цель - научиться писать сервер, который может обслуживать огромное количество клиентов.Моя цель - более 30 000 одновременных клиентов (даже когда мой колледж упоминает, что возможно 500 000, что кажется QUIIITEEE огромной суммой :-)), но я действительно не знаю (даже что возможно), и поэтому я спрашиваюВот.Итак, мой первый вопрос.Сколько одновременных клиентов возможно?Клиенты могут подключаться в любое время и связываться с другими клиентами и формировать группу (1 группа содержит до 12 клиентов).Они могут общаться друг с другом, поэтому размер пакета TCP / IP зависит от отправленного сообщения.Клиенты также могут отправлять математические формулы на сервер.Сервер их решит и передаст ответ обратно группе.Это довольно тяжелая операция.

Мой текущий подход - запустить сервер.Чем использовать fork для создания процесса демона.Процесс демона связывает сокет fd_listen и начинает слушать.Это цикл while (1).Я использую accept () для получения входящих звонков.

После подключения клиента я создаю pthread для этого клиента, который будет выполнять связь.Клиенты добавляются в группу и совместно используют часть памяти (необходимо для поддержания работы группы), но каждый клиент работает в отдельном потоке.Получение доступа к памяти было довольно трудным делом, но теперь работает нормально.

В начале программы я зачитал файл / proc / sys / kernel / threads-max и в соответствии с этим я создаю свои потоки.Количество возможных потоков в соответствии с этим файлом составляет около 5000. Далеко от количества клиентов, которые я хочу иметь возможность обслуживать.Другой подход, который я рассматриваю, заключается в использовании select () и создании наборов.Но время доступа для поиска сокета в наборе равно O (N).Это может быть довольно долго, если у меня подключено более пары тысяч клиентов.Пожалуйста, поправьте меня, если я ошибаюсь.

Ну, я думаю, мне нужны некоторые идеи: -)

Groetjes Markus

PS Я помечаю его для C ++ и C, потому что он применяетсяна оба языка.

Ответы [ 3 ]

4 голосов
/ 02 апреля 2012

На сегодняшний день лучшим подходом является цикл обработки событий , например libev или libevent.

. В большинстве случаев вы обнаружите, что одного потока более чем достаточно, но дажеесли это не так, у вас всегда может быть несколько потоков с отдельными циклами (по крайней мере, с libev).

Libev [ent] использует наиболее эффективное решение для опроса для каждой ОС (и что угодно более эффективен, чем select или поток на сокет).

1 голос
/ 02 апреля 2012

Вы столкнетесь с парой ограничений:

  1. fd_set размер: это можно изменить во время компиляции, но по умолчанию имеет довольно низкий предел, это влияет на select решения.
  2. Поток на сокет исчерпается намного раньше - я предлагаю размещать вычисления long в отдельных потоках (с пулированием, если требуется), но в противном случае подход с одним потоком, вероятно, будет масштабироваться.

Чтобы достичь 500 000, вам понадобится набор компьютеров и круговая DNS, я подозреваю.

TCP-порты не должны быть проблемой, если сервер не подключается к клиентам. Кажется, я всегда об этом забываю, и мне нужно напомнить.

Сами файловые дескрипторы не должны быть слишком большой проблемой, я думаю, но включить их в ваше решение для опроса может быть сложнее - конечно, вы не хотите передавать их каждый раз.

0 голосов
/ 02 апреля 2012

Я думаю, что вы можете использовать модель событий (epoll + пул рабочих потоков) для решения этой проблемы.сначала прослушайте и примите в основном потоке, если клиент подключается к серверу, основной поток распределяет client_fd одному рабочему потоку и добавляет список epoll, тогда этот рабочий поток будет обрабатывать запрос от клиента.

Количество рабочих потоков может быть настроено проблемой, и оно должно быть не более 5000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...