Очень интересует такая тема.
Имеем TCP сервер под Win32 который скажем обслуживает 1000 входящих TCP соединений. Передача данных в каждом из socket происходит с переодичностью примерно раз в 15 секунд.
Текущая реализация на каждое входящее подключение создает thread в котором и будет производиться блокирующее чтение\запись в соответсвующий socket. Поэтому имеем картину 1 listening thread, и по 1 thread'у на каждое TCP подключение.
С целью увеличения эффективности/производительности сервера возникла идея чтобы в одном потоке обслуживать несколько socket'ов. Планируемый прирост производительности ожидается за счет уменьшения накладных расходов на обслуживание thread'ов операционной системой.
Подобное функционирование (thread'ов меньше чем активных TCP соединений) наблюдается у Microsoft SQL Server'a. Наблюдал ситуацию когда к нему по протоколу TCP было более 300 соединений но в это же время счетчик потоков в в диспетчере задач Windows не превышал и 100.
Имеет ли смысл реализовывать описанный функционал?
Если кто-то встречался с обсуждением подобной темы в статьях, книгах будьте добры угостить ссылочкой.
Примерная схема реализации описанного функционала:
1 listening thread принимает подключение и передает его в pool обслуживающих потоков.
Каждый обслуживающий поток может иметь несолько TCP socket-ов. Возможность параллельной обработки нескольких socket-ов в одном потоке в один период времени планируется реализовать на .NET.
Насколько будет эффективен данный подход? Или есть какие то более эффективный алгоритмы реализации описанного функционала?
H>Примерная схема реализации описанного функционала
Обычный поток с массивом неблокирующихся сокетов. В потоке цикл опроса сокетов и отправки подготовленных данных.
Сложностей вроде не должно быть.
H>Насколько будет эффективен данный подход? Или есть какие то более эффективный алгоритмы реализации описанного функционала?
Очень любопытный вопрос. Возможно, мой ответ банален, но я бы посоветовал копать в направлении асинхронных сокетов и QueueUserWorkItem, причем копать, в общем-то, придется неглубоко.
Однако, насколько я помню (на 100% не уверен), .net-овский ThreadPool не является в полной мере ThreadPool-ом. Т.е. он просто предоставляет какое-то кол-во потоков и распределяет по ним запросы. Однако в WinNT реализована куда более интерестная концепция (см. QueueUserWorkItem в MSDN, не путать с .net-овским аналогом или читай Рихтера).
Там не только есть прямая привязка к операциям ввода/вывода, но нечто большее — когда рабочий поток из пула находится в ожидании завершения операции ввода/вывода, для обслуживания новых запросов может быть выделен новый поток, который позднее "умрет", когда в нем отпадет нужда. Таким образом, общее кол-во активных потоков всегда поддерживается разумным (оптимальным). Вот использование этого механизма и должно быть максимально эффективным способом решения твоей проблемы.
могу сказать следующее — когда исследовал производительность различных вариантов использования потоков,
получил ~10Mb/s (на пакетах по 300б) для системы с потоком на сокет (100 сокетов), и ~5Mb/s для системы использующей _стандартный_ threadpool .NET ( точнее, с использованием BeginReceive для приема ) — при такой работе в прога использовала где-то 10-15 потоков всего, отсюда вывод — падение производительности не сильно большое по сравнению с более простой системой, зато мастабируируемость всяко превосходит ( пропускная способность вообще не зависит от количества открытых сокетов)
Здравствуйте, hallucinogenlsd, Вы писали:
H>Доброго времени суток!
H>Очень интересует такая тема. H>Имеем TCP сервер под Win32 который скажем обслуживает 1000 входящих TCP соединений. Передача данных в каждом из socket происходит с переодичностью примерно раз в 15 секунд. H>Текущая реализация на каждое входящее подключение создает thread в котором и будет производиться блокирующее чтение\запись в соответсвующий socket. Поэтому имеем картину 1 listening thread, и по 1 thread'у на каждое TCP подключение.
H>С целью увеличения эффективности/производительности сервера возникла идея чтобы в одном потоке обслуживать несколько socket'ов. Планируемый прирост производительности ожидается за счет уменьшения накладных расходов на обслуживание thread'ов операционной системой.
H>Подобное функционирование (thread'ов меньше чем активных TCP соединений) наблюдается у Microsoft SQL Server'a. Наблюдал ситуацию когда к нему по протоколу TCP было более 300 соединений но в это же время счетчик потоков в в диспетчере задач Windows не превышал и 100.
H>Имеет ли смысл реализовывать описанный функционал?
H>Если кто-то встречался с обсуждением подобной темы в статьях, книгах будьте добры угостить ссылочкой.
H>Примерная схема реализации описанного функционала:
H>1 listening thread принимает подключение и передает его в pool обслуживающих потоков. H>Каждый обслуживающий поток может иметь несолько TCP socket-ов. Возможность параллельной обработки нескольких socket-ов в одном потоке в один период времени планируется реализовать на .NET.
H>Насколько будет эффективен данный подход? Или есть какие то более эффективный алгоритмы реализации описанного функционала?
Я пришел к выводу что самым эффективным способом для работы в .net с сокетами являются асинхронные сокеты.