LINUX.ORG.RU

многопоточный сервер


0

0

я пытаюсь написать сервер одновременно обслуживающий большое количество долгоживущих соединений ( максимум 10 000 ). Сейчас я пытаюсь группировать несколько соединений в одной нити, например на одна нить обслуживает 100 соединений, но испытываю при этом жуткий геморой с синхронизацией.

Вопрос - а надо ли мне это? Может не стоит заморачиваться и порождать на каждое входящее соединение отдельную нить? Сколько потоков я смогу породить прежде чем системе поплохеет?

Машины используются многопроцессорные и многоядерные. Язык с++, библиотека для работы с сокетами - Boost.Asio.

★★

если памяти не жалко - делай.

anonymous
()

> я пытаюсь написать сервер одновременно обслуживающий большое количество долгоживущих соединений ( максимум 10 000 ). Сейчас я пытаюсь группировать несколько соединений в одной нити, например на одна нить обслуживает 100 соединений, но испытываю при этом жуткий геморой с синхронизацией.

как именно? select в каждом треде?

> Вопрос - а надо ли мне это?

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

> Может не стоит заморачиваться и порождать на каждое входящее соединение отдельную нить?

может стоит написать тест, эмулирующий поведение клиентов и посмотреть на сколько сильно будет загружен сервер?

> Сколько потоков я смогу породить прежде чем системе поплохеет?

пишите тест. по крайней мере явно меньше, чем sysctl -e kernel.threads-max

asgard
()
Ответ на: комментарий от asgard

>как именно? select в каждом треде?

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

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

Боюсь что стоимость разработки такого теста превысит стоимость самого сервера :( Но, я попробую.

kernel.threads-max=131072 Я думаю, что мне хватит и десятой части.

Vinick ★★
() автор топика
Ответ на: комментарий от execve

вот я и думаю стоит ли мне перейти от модели #5 к модели #4, но исходя из этого документа - не стоит.

Vinick ★★
() автор топика
Ответ на: комментарий от Vinick

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

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

asgard
()

> Вопрос - а надо ли мне это? Может не стоит заморачиваться и порождать на каждое входящее соединение отдельную нить? Сколько потоков я смогу породить прежде чем системе поплохеет?

Тебе нужно 10000 нитей. Если считать стек по 0.5Mб, то на это уйдет 5Гб.

Дальнейшее обсуждение имеет смысл?

anonymous
()
Ответ на: комментарий от roy

В возможности уменьшения стека нет никаких сомнений.

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

Если автор топика к ним не относиться, то можно попытаться придумать еще какие-нибудь аргументы в пользу неразумности создания 10000 нитей.

anonymous
()
Ответ на: комментарий от anonymous

> можно попытаться придумать еще какие-нибудь аргументы в пользу неразумности создания 10000 нитей.

Из ссылки выше:

4.
...
  Минусы:
    - В зависимости от OS, модель может быть как неэффективной (Linux,
      так как нить "весит" почти столько же, сколько и процесс), так и
      не масштабируемой с ростом числа процессоров (FreeBSD libc_r
      с user-space threads).
    - (Igor Khasilev) Если планируется обслуживать одновременно большое число
      подключенных клиентов (от тысячи и выше в зависимости от ОС) эта модель
      может оказаться нерабочей по причинам: расход адресного пространства
      на стек для каждой нити, большая нагрузка на планировщик и
      ограничение на общее число нитей в системе (особенно в случае
      1:1 модели). Иногда может спасти экстенсивный путь - переход на
      64-битные платформы.
    - Существенно затрудняется отладка. 

execve
()
Ответ на: комментарий от tailgunner

> Интересно, как они "взвешивали"

Спроси у них сам. Я подозреваю, что имелось ввиду "с точки зрения планировщика"

execve
()
Ответ на: комментарий от anonymous

>а если сменить язык?

Ну вот так всегда, сначала предлагают сменить язык, потом платформу, а потом и пол и сексуальную ориентацию. :)

>проде erlang как раз писался для того то-бы делать подобные вещи... я не уверен, что erlang не даст просадки производительности по сравнению с С++.

И вобще, коней на переправе не меняют.

Vinick ★★
() автор топика
Ответ на: комментарий от Vinick

Спасибо всем за комментарии. Все-таки я решил добить существующую модель, с объединением нескольких соединений в одном потоке.

Vinick ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.