是Socket。*异步方法是否有线程?

我目前正在尝试确定什么是最小化我在TCP主服务器中使用的线程数量的最佳方法,以便最大限度地提高性能。

由于我最近在使用C#5.0的新异步function阅读了很多内容,异步并不一定意味着multithreading。 它可能意味着在较小的有限状态对象块中分离,然后通过交替处理与其他操作一起处理。 但是,我不知道如何在网络中做到这一点,因为我基本上“等待”输入(来自客户端)。

因此,我不会对所有套接字使用ReceiveAsync(),它只是连续创建和结束线程(假设它确实创建了线程)。

因此,我的问题或多或少:主服务器可以在没有每个连接一个“线程”的情况下采用什么架构?

奖励酷点的一个问题:为什么multithreading坏了,考虑到拥有一定数量的线程超过你的处理内核数量只会使机器“假”multithreading,就像任何其他异步方法一样?

好像*Async方法使用IOCP(通过使用Reflector查看代码)。

不,你不一定会创建线程。 有两种方法可以在不设置和逐渐删除线程的情况下执行异步操作:

  1. 你可以拥有一个“小”数量的长期线程,并且在没有工作要做时让它们hibernate(这意味着操作系统永远不会安排它们执行,因此资源消耗很小)。 然后,当工作到达时(即调用Async方法),唤醒其中一个并告诉它需要做什么。 很高兴见到你, 托管线程池 。
  2. 在Windows中,最有效的异步机制是I / O完成端口 ,它可以同步对I / O操作的访问,并允许少量线程管理大量工作负载。

关于multithreading:

如果有多个线程对性能不错

  • 线程数量不会过多
  • 线程不会使CPU过饱和

如果线程数量过多,那么显然我们要对操作系统征税,必须跟踪并安排所有这些线程,这会占用全局资源并减慢速度。

如果线程受CPU限制,那么操作系统将需要执行更频繁的上下文切换以保持公平性,并且上下文切换会降低性能。 事实上,对于用户模式线程 (所有高度可扩展的系统都使用 – 想想RDBMS),我们的生活更加艰难,因此我们可以避免上下文切换。

更新:

我刚刚发现了这个问题 ,它支持你不能预先确定多少线程太多的位置 – 有太多未知变量。

乔恩的回答很棒。 至于“附带问题”……请参阅http://en.wikipedia.org/wiki/Amdahl%27s_law 。 Amdel的定律表明,串行代码很快就会降低并行代码的收益。 我们还知道线程协调(调度,上下文切换等)是串行的 – 因此在某些时候,更multithreading意味着有如此多的串行步骤,以至于并行化优势会丢失,并且您具有净负面性能。 这是棘手的事情。 这就是为什么在我们为框架定义“任务”以决定运行什么线程时让.NET管理线程需要付出那么多努力。 框架可以比操作系统在线程之间切换更有效地在任务之间切换,因为操作系统在执行此操作时需要担心许多额外的事情。

异步工作可以在没有单线程每个连接的情况下完成,也可以在操作系统支持selectpoll使用线程池(Windows支持此function并通过Socket.Select公开 )。 我不确定Windows上的性能,但这是其他地方非常常见的习惯用法。

一个线程是“泵”,它管理IO连接并监视对流的更改,然后向/从其他线程发送消息(可以想象为0 … n,具体取决于型号)。 具有0或1个附加线程的方法可能属于“事件机器”类别,如twisted(Python)或POE(Perl)。 使用> 1个线程,调用者形成一个“隐式线程池”(自己),基本上只是卸载阻塞IO。

在某些语言的基础模型中也暴露了诸如Actors, Continuations或Fibers之类的方法,这些方法改变了基本问题的处理方式 – 不要等待,做出反应。

快乐的编码。