Являются ли Socket. * Асинхронные методы многопоточными? - PullRequest
7 голосов
/ 19 марта 2011

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

Как я недавно много читал с новыми функциями асинхронности в C # 5.0, асинхронность не обязательно означает многопоточность. Это может означать разделение на более мелкие порции объектов конечного состояния, а затем обработка поочередно с другими операциями. Однако я не понимаю, как это можно сделать в сети, поскольку я в основном "жду" ввода (от клиента).

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

Следовательно, мой вопрос более или менее таков: какую архитектуру может использовать главный сервер, не имея одного «потока» на соединение?

Дополнительный вопрос для бонусных баллов крутости: почему плохо работать с несколькими потоками, учитывая, что количество потоков, превышающее количество обрабатывающих ядер, просто делает машину "фальшивой" многопоточностью, как любой другой асинхронный метод?

Ответы [ 4 ]

8 голосов
/ 19 марта 2011

Нет, вы не обязательно будете создавать темы. Существует два возможных способа асинхронизации без постоянной настройки и удаления потоков:

  1. У вас может быть «небольшое» количество долгоживущих потоков, и они могут спать, когда нет работы (это означает, что ОС никогда не запланирует их выполнение, поэтому утечка ресурсов минимальна). Затем, когда приходит работа (то есть вызывается асинхронный метод), разбудите одного из них и скажите ему, что нужно сделать. Рад знакомству, управляемый пул потоков .
  2. В Windows наиболее эффективным механизмом асинхронности является порты завершения ввода-вывода , который синхронизирует доступ к операциям ввода-вывода и позволяет небольшому количеству потоков управлять большими рабочими нагрузками.

Относительно нескольких потоков:

Наличие нескольких потоков - это не плохо для производительности, , если

  • количество потоков не чрезмерно
  • потоки не перенасыщают процессор

Если количество потоков чрезмерно, то, очевидно, мы облагаем ОС необходимостью отслеживать и планировать все эти потоки, что использует глобальные ресурсы и замедляет их.

Если потоки привязаны к ЦП, то ОС должна будет выполнять гораздо более частые переключения контекста, чтобы поддерживать справедливость, а переключение контекста снижает производительность. Фактически, с потоками пользовательского режима (которые используются во всех высоко масштабируемых системах - например, СУБД), мы усложняем нашу жизнь, просто чтобы избежать переключений контекста.

Обновление:

Я только что нашел этот вопрос , который поддерживает позицию, согласно которой вы не можете заранее сказать, сколько потоков слишком много - слишком много неизвестных переменных.

3 голосов
/ 19 марта 2011

Похоже, что методы *Async используют IOCP (просматривая код с помощью Reflector).

1 голос
/ 19 марта 2011

Ответ Джона великолепен.Что касается «побочного вопроса» ... См. http://en.wikipedia.org/wiki/Amdahl%27s_law. Закон Амделя гласит, что последовательный код быстро уменьшает выгоды от параллельного кода.Мы также знаем, что координация потоков (планирование, переключение контекста и т. Д.) Является последовательной, поэтому в какой-то момент большее количество потоков означает, что существует так много последовательных шагов, что преимущества распараллеливания теряются, и вы получаете чистую отрицательную производительность.Это хитрый материал.Вот почему так много усилий уходит на то, чтобы позволить .NET управлять потоками, пока мы определяем «задачи» для платформы, чтобы решить, на каком потоке работать.Платформа может переключаться между задачами гораздо эффективнее, чем ОС может переключаться между потоками, потому что в ОС есть много дополнительных вещей, о которых нужно беспокоиться при этом.

0 голосов
/ 19 марта 2011

Асинхронная работа может быть выполнена без однопоточное соединение или пул потоков с поддержкой ОС для select или poll (и Windows поддерживает это, и она предоставляется через Socket.Select ).Я не уверен в производительности на Windows, но это очень распространенная идиома в других местах.

Один поток - это «насос», который управляет соединениями ввода-вывода и отслеживает изменения в потоках, а затем отправляет сообщения в / издругие темы (предположительно 0 ... n в зависимости от модели).Подходы с 0 или 1 дополнительными потоками могут попадать в категорию «Event Machine», например, витая (Python) или POE (Perl).При> 1 потоках вызывающие стороны формируют «неявный пул потоков» (сами по себе) и в основном просто снимают блокировку ввода-вывода.

Существуют также подходы, такие как Actors, Continuations или Fibers представлен в базовых моделях некоторых языков, которые изменяют подход к основной проблеме - не ждите, реагируйте.

Удачное кодирование.

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