繁体   English   中英

Socket.ReceiveAsync可以进入C10K吗?

[英]Can Socket.ReceiveAsync head to C10K?

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

我不认为这完全是另一个问题的重复,正如建议的那样: 高性能套接字上的Async-Await与ThreadPool与MultiThreading(C10k解决方案?)这个问题更多地是关于各种线程模型的讨论,并不总是适用于Socket。**** Async(全部使用SocketAsyncEventArgs)。

这个问题的答案在很大程度上取决于您的运行时和操作系统。 我最近在为Unity开发解决方案时走了这条路,所以即使问题有点老,我也将分享我所知道的东西。

让我们首先讨论Windows和MS .NET(实现这些方法时从3.5开始的任何内容)。 在此运行时和平台上组合这些套接字方法时,您肯定可以破坏c10k。 带有SocketAsyncEventArgs参数的**** Async方法可以直接在运行时中进行本机调用,而本机调用将映射到Windows中的IO完成端口。 这是运行时的特殊路径,它的作用不只是防止分配IAsyncResult对象。 我认为在Linux上使用.NET Standard的速度也非常快,但是我不能直接这么说。

接下来,让我们讨论Linux上的Mono。 具体来说,我当前使用的是:Mono C#编译器版本4.6.2.0这也将破坏c10k,但其工作方式有所不同。 据我所知,***** Async方法在运行时的路径与所有其他异步方法相同,但**** Async调用的路径最短,避免了IAsyncResult分配。 运行时通过IOSelector.Add将您的请求作为IOSelectorJob提交。 因此,似乎**** Async方法实际上都不会在Mono中返回false,尽管我不会指望该行为始终为true。 我认为在Windows上使用Mono的速度同样快,但是我不能这么说。

最后,让我们谈谈Unity。 我正在使用具有Mono 5.11.0运行时的2018.3.2f1,设置为.NET 4.x兼容。 我不确定是否可以在Unity中破解c10k。 我不知道为什么,但是我知道在Mono和.NET中轻易破坏c10k的相同实现甚至都不会实现。 我认为这是因为它们的线程池以不同的方式设置了……也许是为了适应他们的工作系统,但这只是一个黑暗的猜测。 发生非常奇怪的事情,例如同步接受优于异步。 永远不会获得回调的AcceptAsync请求,依此类推。

在Unity之外打破c10k的一些技巧:-尽可能减少IO完成回调。 不要像MSDN示例一样在其中调用其他Async方法-如果可以管理,则由于设计原因,不要对SendAsync和ReceiveAsync进行调用彼此阻塞。 您不能使用相同的arg进行2个未完成的调用,但可以同时使用多个和单独的arg(因此还有缓冲区)进行发送/接收。 但是要注意,排序可能会变得很复杂,例如在同一套接字上有多个未完成的recv的情况下,并发队列会从回调中调度返回的args-如果必须在线程之间共享资源,则需要使用System.Collections.Concurrent是你的朋友。 不要自己动手,因为这些容器并不是您不破坏c10k的原因,而且您将永远无法匹配这些婴儿接受的测试数量

祝你好运,并祝您玩得开心:)如果您发现Unity成功的秘诀,请别忘了告诉我。 如果有的话,我一定会更新。

暂无
暂无

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

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