简体   繁体   English

Socket.ReceiveAsync可以进入C10K吗?

[英]Can Socket.ReceiveAsync head to C10K?

使用Socket.ReceiveAsync甚至Socket.SendAsync的TCP套接字能否遇到C10K问题?

I don't think this is at all a duplicate of this other question, as has been suggested: Async-Await vs ThreadPool vs MultiThreading on High-Performance Sockets (C10k Solutions?) That question is more a discussion of various threading models, which don't always apply to Socket.****Async (which ALL use SocketAsyncEventArgs). 我不认为这完全是另一个问题的重复,正如建议的那样: 高性能套接字上的Async-Await与ThreadPool与MultiThreading(C10k解决方案?)这个问题更多地是关于各种线程模型的讨论,并不总是适用于Socket。**** Async(全部使用SocketAsyncEventArgs)。

The answer to this question is HIGHLY dependent upon your runtime and your OS. 这个问题的答案在很大程度上取决于您的运行时和操作系统。 I have just recently gone down this road while developing a solution for Unity, so I will share what I know even though the question is a bit old. 我最近在为Unity开发解决方案时走了这条路,所以即使问题有点老,我也将分享我所知道的东西。

Let's first talk about Windows and MS .NET (anything from 3.5 when those methods were implemented to present). 让我们首先讨论Windows和MS .NET(实现这些方法时从3.5开始的任何内容)。 You can definitely break c10k when combining those socket methods on this runtime and platform. 在此运行时和平台上组合这些套接字方法时,您肯定可以破坏c10k。 The ****Async methods that take a SocketAsyncEventArgs parameter go straight to native calls in the runtime, which map to IO Completion Ports in Windows. 带有SocketAsyncEventArgs参数的**** Async方法可以直接在运行时中进行本机调用,而本机调用将映射到Windows中的IO完成端口。 This is a special path through the runtime, which does more than prevent allocating IAsyncResult objects. 这是运行时的特殊路径,它的作用不只是防止分配IAsyncResult对象。 I assume using .NET Standard on Linux is also very fast, but I cannot speak directly to that. 我认为在Linux上使用.NET Standard的速度也非常快,但是我不能直接这么说。

Next, let's talking about Mono on Linux. 接下来,让我们讨论Linux上的Mono。 Specifically, I am currently building with: Mono C# compiler version 4.6.2.0 This will also break c10k, but it works differently. 具体来说,我当前使用的是:Mono C#编译器版本4.6.2.0这也将破坏c10k,但其工作方式有所不同。 From what I can see, the *****Async methods take the same path through the runtime as all other async methods, except ****Async calls take the shortest path and avoid an IAsyncResult allocation. 据我所知,***** Async方法在运行时的路径与所有其他异步方法相同,但**** Async调用的路径最短,避免了IAsyncResult分配。 The runtime submits your requests as an IOSelectorJob via IOSelector.Add. 运行时通过IOSelector.Add将您的请求作为IOSelectorJob提交。 For this reason it appears that none of the ****Async methods will actually ever return false in Mono, though I wouldn't count on that behaviour always being true. 因此,似乎**** Async方法实际上都不会在Mono中返回false,尽管我不会指望该行为始终为true。 I assume using Mono on Windows is equally fast, but I cannot speak to that. 我认为在Windows上使用Mono的速度同样快,但是我不能这么说。

Finally, let's talk about Unity. 最后,让我们谈谈Unity。 I am using 2018.3.2f1 which has the Mono 5.11.0 runtime, set to .NET 4.x compat. 我正在使用具有Mono 5.11.0运行时的2018.3.2f1,设置为.NET 4.x兼容。 I'm not sure it is possible to break c10k in Unity. 我不确定是否可以在Unity中破解c10k。 I don't know why, but I know that identical implementations that handily break c10k in Mono and .NET will not even come close. 我不知道为什么,但是我知道在Mono和.NET中轻易破坏c10k的相同实现甚至都不会实现。 I assume this is because somehow their thread pools are set up differently ... perhaps to accomodate their job system, but that's merely a shot-in-the-dark guess. 我认为这是因为它们的线程池以不同的方式设置了……也许是为了适应他们的工作系统,但这只是一个黑暗的猜测。 Very strange things happen, such as synchronous accept outperforming async. 发生非常奇怪的事情,例如同步接受优于异步。 AcceptAsync requests that never get a callback, and so on. 永远不会获得回调的AcceptAsync请求,依此类推。

Some tips to break c10k outside of Unity: - Do as little as possible in your IO completion callbacks. 在Unity之外打破c10k的一些技巧:-尽可能减少IO完成回调。 Don't put calls to other Async methods inside them like the MSDN example - If you can manage it, don't make calls to SendAsync and ReceiveAsync block each other due to your design. 不要像MSDN示例一样在其中调用其他Async方法-如果可以管理,则由于设计原因,不要对SendAsync和ReceiveAsync进行调用彼此阻塞。 You can't have 2 outstanding calls with the same arg, but you can have both multiple and separate args (and therefore buffers) for send/recv. 您不能使用相同的arg进行2个未完成的调用,但可以同时使用多个和单独的arg(因此还有缓冲区)进行发送/接收。 But be aware that things can get complicated for ordering, for example in the case of multiple outstanding recvs on the same socket, and concurrent queues dispatching the returned args from the callbacks - If you have to share resources between threads then System.Collections.Concurrent is your friend. 但是要注意,排序可能会变得很复杂,例如在同一套接字上有多个未完成的recv的情况下,并发队列会从回调中调度返回的args-如果必须在线程之间共享资源,则需要使用System.Collections.Concurrent是你的朋友。 Don't roll your own as these containers are not why you aren't breaking c10k, and you will never be able to match the amount of testing these babies have undergone 不要自己动手,因为这些容器并不是您不破坏c10k的原因,而且您将永远无法匹配这些婴儿接受的测试数量

Good luck and have fun :) And don't forget to tell me if you find the secret to success in Unity. 祝你好运,并祝您玩得开心:)如果您发现Unity成功的秘诀,请别忘了告诉我。 I'll surely update this if I do. 如果有的话,我一定会更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM