我目前正在尝试确定什么是最小化我在TCP主服务器中使用的线程数量的最佳方法,以便最大限度地提高性能。
由于我最近阅读了很多C#5.0的新异步功能,异步并不一定意味着多线程。它可能意味着在较小的有限状态对象块中分离,然后通过交替处理与其他操作一起处理。但是,我不知道如何在网络中做到这一点,因为我基本上“等待”输入(来自客户端)。
因此,我不会对所有套接字使用ReceiveAsync(),它只是连续创建和结束线程(假设 创建线程)。
因此,我的问题或多或少:主服务器在没有每个连接一个“线程”的情况下可以采用什么架构?
奖励酷点的一个问题:为什么多线程坏了,考虑到拥有超过处理核心数量的线程数量只会使机器“假”多线程,就像任何其他异步方法一样? / p>
答案 0 :(得分:8)
不,你不一定要创建线程。您可以通过两种方式进行异步,而无需始终设置和删除线程:
关于多线程:
拥有多个线程对性能而言并不坏, if
如果线程数过多,那么显然我们要对操作系统征税,必须跟踪并安排所有这些线程,这会消耗全局资源并减慢它的速度。
如果线程受CPU限制,那么操作系统将需要执行更频繁的上下文切换以保持公平性,并且上下文切换会降低性能。实际上,使用user-mode threads(所有高度可扩展的系统都使用 - 想想RDBMS),我们的生活更加艰难,因此我们可以避免上下文切换。
<强>更新强>
我刚刚发现this question,它支持你不能预先知道多少线程太多的位置 - 有太多未知变量。
答案 1 :(得分:3)
似乎*Async
方法使用IOCP(通过使用Reflector查看代码)。
答案 2 :(得分:1)
Jon的回答很棒。至于“附带问题”......见http://en.wikipedia.org/wiki/Amdahl%27s_law。 Amdel的定律表明,串行代码很快就会降低并行代码的收益。我们还知道线程协调(调度,上下文切换等)是串行的 - 因此在某些时候,更多线程意味着有如此多的串行步骤,以至于并行化优势会丢失,并且您具有净负面性能。这很棘手。这就是为什么在我们为框架定义“任务”以决定运行什么线程的同时让.NET管理线程的努力。该框架可以比操作系统在线程之间切换更有效地在任务之间切换,因为操作系统在执行此操作时需要担心许多额外的事情。
答案 3 :(得分:0)
异步工作可以在没有一个线程的每个连接的情况下完成,或者是一个支持select
或poll
的操作系统的线程池(Windows支持这个,它是通过Socket.Select暴露出来。我不确定Windows上的性能,但这是其他地方非常常见的习惯用法。
一个线程是“泵”,它管理IO连接并监视对流的更改,然后向/从其他线程发送消息(可以想象为0 ... n,具体取决于型号)。具有0或1个附加线程的方法可能属于“事件机器”类别,如twisted(Python)或POE(Perl)。使用&gt; 1个线程,调用者形成一个“隐式线程池”(本身),基本上只是卸载阻塞IO。
在一些语言的基础模型中也暴露了类似Actors,Continuations或Fibres的方法,这些方法会改变基本问题的处理方式 - 不要等待,做出反应。
快乐的编码。