Многопоточный сервер, вопрос узкого места - PullRequest
0 голосов
/ 01 ноября 2009

Я занимаюсь разработкой многопоточного сервера, который до сих пор работал хорошо - 1 отдельный поток для принятия клиента, пул потоков для чтения и обработки данных. Сегодня я добавил новую ветку для некоторых вещей и отправки сообщений клиенту каждые 500 мс (всего 2-5 сообщений). Я заметил довольно значительное замедление, но я не уверен, почему - его отдельный поток и его нет из-за итераций и блокировок коллекций, потому что когда я добавлял // перед вызовом SendMessage, он все еще был так же быстр, как и раньше. SendMessage в основном выполняет итерации всех подключенных клиентов и для каждого из них вызывает метод SendData, который записывает данные в их сетевой поток. Что мне не хватает? Я все еще думаю, что это разные темы, и я надеюсь, что это не из-за stream.write .. Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 01 ноября 2009

Потоки и пулы потоков для таких вещей, как серверы сокетов, - это старый способ работы. Это очень масштабируемо (оптимально, чтобы вы не хотели иметь больше потоков, чем ядер), и полно блокировок.

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

Я знаю совет: нет, нет, переписывайте все, что вы должны сделать, как это, это не очень полезно, так как не отвечает на точный вопрос, который вы задали. Но если у вас есть время, я все равно думаю, что это хороший совет. Или же это хороший совет для следующего сервера, который вы создадите; ^)

0 голосов
/ 01 ноября 2009

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

Во-первых, чисто общие советы.

Это хорошее время, чтобы достать профилировщик. Такое предположение заманчиво и часто является хорошим умственным упражнением, но большую часть времени программисты ошибаются в том, что, по их мнению, замедляет работу их программного обеспечения . Профилировщик скажет вам, например, если ваша программа тратит 90% своего времени выполнения в одном методе.

Во-вторых, умозрительное предположение.

Звучит так, будто ваша команда сообщений запускается по таймеру. Убедитесь, что у вас нет проблем с повторным входом - например, если ваш цикл отправки сообщений занимает более 500 мс (и вместе с созданием нового потока и множеством непредсказуемых сетевых вызовов с задержкой это вполне может сделать это), и у вас есть все операции в блокировке, тогда таймер будет продолжать порождать потоки пула потоков, которые сидят в этой блокировке, ожидая завершения предыдущей операции - и имеется конечное число доступных потоков пула потоков. Чтобы проверить, является ли это проблемой, вам даже не нужен профилировщик, когда задержка становится плохой, приостановите отладчик и проверьте свой список текущих выполняющихся потоков.

Если это так, подумайте о том, чтобы сделать что-то еще, например, иметь один поток, который работает в бесконечном цикле, используя ручку ожидания в качестве механизма блокировки и таймер, который устанавливает ручку ожидания каждые 500 мс.

Но вам будет гораздо легче помочь, если вы разместите некоторые фрагменты кода и запустите профилировщик (Ants или DotTrace оба отлично работают).

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