使用Socket.ReceiveAsync甚至Socket.SendAsync的TCP套接字会遇到C10K问题吗?
发布于 2019-01-28 03:39:38
我不认为这与其他问题是重复的,正如有人所建议的那样:异步等待对ThreadPool和MultiThreading在高性能套接字上(C10k解决方案?)这个问题更多地是对各种线程模型的讨论,这些模型并不总是适用于套接字。*异步(所有这些模型都使用SocketAsyncEventArgs)。
这个问题的答案在很大程度上取决于您的运行时和操作系统。我最近刚走上这条路,正在开发一个统一的解决方案,所以我将分享我所知道的,尽管这个问题有点老了。
让我们首先讨论一下Windows和MS .NET (这些方法实现到现在时的任何内容)。在此运行时和平台上组合这些套接字方法时,绝对可以破坏c10k。接受SocketAsyncEventArgs参数的*异步方法直接进入运行时中的本机调用,后者映射到Windows中的IO完成端口。这是贯穿运行时的一个特殊路径,它不仅阻止分配IAsyncResult对象。我认为在Linux上使用.NET标准也是非常快的,但我不能直接说。
接下来,让我们讨论一下Linux上的Mono。具体来说,我目前正在使用: Mono C#编译器4.6.2.0版本构建--这也会破坏c10k,但它的工作方式不同。据我所见,*异步方法在运行时采取与所有其他异步方法相同的路径,除了*异步调用采用最短路径并避免IAsyncResult分配。运行时以IOSelectorJob的形式通过IOSelector.Add提交请求。由于这个原因,在Mono中,似乎没有一个*异步方法实际上会返回false,尽管我不认为这种行为总是正确的。我认为在Windows上使用Mono也同样快,但我不能这样说。
最后,让我们谈谈团结。我使用的是2018.3.2f1,它的Mono5.11.0运行时设置为.NET 4.xcompat。我不确定是否有可能打破c10k在统一。我不知道为什么,但我知道,在Mono和.NET中轻松破坏c10k的相同实现甚至不会接近。我想这是因为他们的线程池设置方式不同.也许是为了适应他们的工作体系,但这只是一种暗箱猜测。非常奇怪的事情会发生,例如同步接受优于异步。永远得不到回调的AcceptAsync请求,等等。
一些技巧,以打破c10k以外的团结:-做尽可能少在你的IO完成回调。不要在其中调用其他异步方法,比如MSDN示例--如果您可以管理它,就不要因为您的设计而相互调用SendAsync和ReceiveAsync。不能使用相同的arg调用两个未完成的调用,但是可以为send/recv提供多个和单独的arg(因此也包括缓冲区)。但是请注意,排序可能会变得复杂,例如,在同一个套接字上有多个未完成的recv,以及并发队列从回调中分派返回的args --如果您必须在线程之间共享资源,那么System.Collections.Concurrent就是您的朋友。不要自己翻滚,因为这些容器不是你没有破坏c10k的原因,而且你永远无法与这些婴儿所经历的检测量相匹配。
祝你好运,玩得开心:)别忘了告诉我,你是否在团结中找到了成功的秘诀。如果我知道的话,我一定会更新的。
https://stackoverflow.com/questions/50482966
复制相似问题