Может ли Socket.ReceiveAsync отправиться в C10K?

Может ли TCP-сокет, использующий Socket.ReceiveAsync или даже Socket.SendAsync, столкнуться с проблемой C10K?

0 ответов

Я не думаю, что это вообще дубликат этого другого вопроса, как было предложено: Async-Await против ThreadPool против MultiThreading на высокопроизводительных сокетах (решения C10k?). Этот вопрос больше является обсуждением различных моделей потоков, которые не всегда применяется к Socket.****Async (которые ВСЕ используют SocketAsyncEventArgs).

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

Давайте сначала поговорим о Windows и MS .NET (начиная с 3.5, когда эти методы были реализованы, чтобы представить). Вы можете определенно сломать c10k, комбинируя эти методы сокетов в этой среде выполнения и платформе. Методы **** Async, которые принимают параметр SocketAsyncEventArgs, сразу переходят к собственным вызовам во время выполнения, которые сопоставляются с портами завершения ввода-вывода в Windows. Это особый путь в среде выполнения, который не только предотвращает выделение объектов IAsyncResult. Я предполагаю, что использование.NET Standard в Linux также очень быстро, но я не могу говорить об этом напрямую.

Далее давайте поговорим о Mono в Linux. В частности, я в настоящее время собираюсь с: Mono C# компилятор версии 4.6.2.0 Это также сломает c10k, но работает по-другому. Из того, что я вижу, ***** асинхронные методы берут тот же путь в среде выполнения, что и все другие асинхронные методы, за исключением **** асинхронных вызовов, которые берут самый короткий путь и избегают распределения IAsyncResult. Среда выполнения отправляет ваши запросы как IOSelectorJob через IOSelector.Add. По этой причине кажется, что ни один из методов **** Async фактически никогда не вернет false в Mono, хотя я бы не рассчитывал, что такое поведение всегда будет истинным. Я предполагаю, что использование Mono в Windows одинаково быстро, но я не могу говорить об этом.

Наконец, давайте поговорим об Unity. Я использую 2018.3.2f1, который имеет среду выполнения Mono 5.11.0, установленную на.NET 4.x compat. Я не уверен, что можно сломать c10k в Unity. Я не знаю почему, но я знаю, что идентичные реализации, которые легко ломают c10k в Mono и.NET, даже близко не подойдут. Я предполагаю, что это потому, что их пулы потоков настроены по-другому... возможно, чтобы приспособиться к их системе работы, но это всего лишь предположение о том, как делать это в темноте. Происходят очень странные вещи, такие как синхронный прием, превосходящий асинхронный. AcceptAsync запросы, которые никогда не получают обратный вызов и т. Д.

Несколько советов, как сломать c10k вне Unity: - Делайте как можно меньше в ваших обратных вызовах завершения ввода-вывода. Не помещайте в них вызовы других методов Async, как, например, в примере MSDN. Если вы можете управлять им, не выполняйте вызовы SendAsync и ReceiveAsync блокируют друг друга из-за вашего дизайна. У вас не может быть двух ожидающих вызовов с одним и тем же аргументом, но вы можете иметь как несколько, так и отдельные аргументы (и, следовательно, буферы) для отправки / записи. Но имейте в виду, что порядок упорядочения может быть сложным, например, в случае нескольких невыполненных recvs на одном сокете и одновременных очередей, отправляющих возвращенные аргументы из обратных вызовов - если вам нужно совместно использовать ресурсы между потоками, тогда System.Collections.Concurrent твой друг. Не катайте свои собственные, так как эти контейнеры не являются причиной того, что вы не разбили C10K, и вы никогда не сможете сравниться с количеством тестов, которые эти дети прошли

Удачи и веселья:) И не забудьте сказать мне, если вы найдете секрет успеха в Unity. Я обязательно обновлю это, если я сделаю.

Другие вопросы по тегам