是Socket.*Async方法是否有线程?

Laz*_*zlo 7 .net c# sockets multithreading asynchronous

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

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

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

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

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

Jon*_*Jon 8

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

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

关于多线程:

有多个线程是不坏的表现,如果

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

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

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

更新:

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


Ben*_*igt 3

似乎这些*Async方法使用了 IOCP(通过使用 Reflector 查看代码)。