У меня есть сервер, прослушивающий сокеты, какой хороший подход к обслуживанию запросов, привязанных к процессору, с несколькими потоками?

StackOverflow https://stackoverflow.com/questions/1167933

Вопрос

У меня есть приложение, написанное на C ++, которое использует boost::asio.Он прослушивает запросы в сокете и для каждого запроса выполняет некоторую работу, связанную с процессором (напримернет дискового или сетевого ввода-вывода), а затем выдает ответ.

Это приложение будет работать в многоядерной системе, поэтому я планирую иметь (как минимум) 1 поток на ядро для параллельной обработки запросов.

Какой здесь наилучший подход?Есть о чем подумать:

  • Мне понадобится пул потоков фиксированного размера (например1 поток на процессор)
  • Если поступает больше запросов, чем у меня потоков, то их нужно будет поставить в очередь (возможно, на уровне сокетов o / s?)

В настоящее время сервер является однопоточным:

  • Он ожидает запроса клиента
  • Как только он получает запрос, он выполняет работу и записывает ответ обратно, затем начинает ждать следующего запроса

Обновить:

Более конкретно:какой механизм я должен использовать, чтобы гарантировать, что если сервер занят, входящие запросы будут поставлены в очередь?Какой механизм я должен использовать для распределения входящих запросов между N потоками (по 1 на ядро)?

Это было полезно?

Решение

Я не вижу, чтобы было что-то, что вы еще не рассмотрели, заслуживающее внимания.

Если он действительно привязан к процессору, то добавление потоков, превышающих количество ядер, вам не сильно поможет за исключением если у вас будет много запросов.В этом случае очередь прослушивания может соответствовать или не соответствовать вашим потребностям, и, возможно, было бы лучше иметь несколько потоков, которые принимали бы соединения и ставили их в очередь самостоятельно.Проверьте значения listen backlog для вашей системы и немного поэкспериментируйте с количеством потоков.

Обновить:

listen() имеет второй параметр, который является запрошенной вами глубиной очереди OS / TCP.Вы можете настроить его на пределе возможностей операционной системы.Кроме того, вам нужно поиграть с системными ручками.В моей текущей системе он равен 128, так что он не огромен, но и не тривиален.Проверьте свою систему и подумайте, действительно ли вам нужно что-то большее, чем стандартное.

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

При нынешних темпах обновления моего дистрибутива Boost (и моем нежелании компилировать его самостоятельно) я начну играть с ASIO только в 2012 году, так что я ничего не могу с этим поделать.

Другие советы

туз http://www.cs.wustl.edu /~шмидт/ТУЗ/книга 1/

Здесь есть все, что вам нужно.Управление потоками и очередями и в качестве дополнительного бонуса портативный способ написания серверов сокетов.

Если вы используете перегруженный конструктор basic_socket_acceptor для привязки и прослушивания заданной конечной точки, он использует SOMAXCONN в качестве списка незавершенных подключений в вызове listen().Я думаю (не очень уверен), что это соответствует 250 в Windows.Таким образом, поставщик сетевых услуг будет (молча) принимать клиентские подключения до этого предела и ставить их в очередь для обработки вашим приложением.Ваш следующий вызов accept приведет к появлению соединения из этой очереди.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top