Может ли Socket.ReceiveAsync отправиться в C10K? - PullRequest
0 голосов
/ 23 мая 2018

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

1 Ответ

0 голосов
/ 28 января 2019

Я не думаю, что это вообще дубликат этого другого вопроса, как было предложено: 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 блокируют друг друга из-за вашего дизайна.Вы не можете иметь 2 невыполненных вызова с одним и тем же аргументом, но вы можете иметь как несколько, так и отдельные аргументы (и, следовательно, буферы) для отправки / записи.Но имейте в виду, что порядок упорядочения может быть сложным, например, в случае нескольких невыполненных recvs на одном сокете и одновременных очередей, отправляющих возвращенные аргументы из обратных вызовов - если вам нужно совместно использовать ресурсы между потоками, тогда System.Collections.Concurrentтвой друг.Не катайте свои собственные, так как эти контейнеры не являются причиной того, что вы не разбили C10K, и вы никогда не сможете сравниться с количеством тестов, которые эти дети прошли

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

...